/*
Copyright (C) 2018-2019 de4dot@gmail.com

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#if ENCODER
using System;
using System.Diagnostics;

namespace Iced.Intel {
	// GENERATOR-BEGIN: RepPrefixKind
	// ⚠️This was generated by GENERATOR!🦹‍♂️
	/// <summary><c>REP</c>/<c>REPE</c>/<c>REPNE</c> prefix</summary>
	public enum RepPrefixKind {
		/// <summary>No <c>REP</c>/<c>REPE</c>/<c>REPNE</c> prefix</summary>
		None = 0,
		/// <summary><c>REP</c>/<c>REPE</c> prefix</summary>
		Repe = 1,
		/// <summary><c>REPNE</c> prefix</summary>
		Repne = 2,
	}
	// GENERATOR-END: RepPrefixKind

	partial struct Instruction {
		static void InitializeSignedImmediate(ref Instruction instruction, int operand, long immediate) {
			var opKind = GetImmediateOpKind(instruction.Code, operand);
			instruction.SetOpKind(operand, opKind);

			switch (opKind) {
			case OpKind.Immediate8:
				// All sbyte and all byte values can be used
				if (!(sbyte.MinValue <= immediate && immediate <= byte.MaxValue))
					throw new ArgumentOutOfRangeException(nameof(immediate));
				instruction.InternalImmediate8 = (byte)immediate;
				break;

			case OpKind.Immediate8_2nd:
				// All sbyte and all byte values can be used
				if (!(sbyte.MinValue <= immediate && immediate <= byte.MaxValue))
					throw new ArgumentOutOfRangeException(nameof(immediate));
				instruction.InternalImmediate8_2nd = (byte)immediate;
				break;

			case OpKind.Immediate8to16:
				if (!(sbyte.MinValue <= immediate && immediate <= sbyte.MaxValue))
					throw new ArgumentOutOfRangeException(nameof(immediate));
				instruction.InternalImmediate8 = (byte)immediate;
				break;

			case OpKind.Immediate8to32:
				if (!(sbyte.MinValue <= immediate && immediate <= sbyte.MaxValue))
					throw new ArgumentOutOfRangeException(nameof(immediate));
				instruction.InternalImmediate8 = (byte)immediate;
				break;

			case OpKind.Immediate8to64:
				if (!(sbyte.MinValue <= immediate && immediate <= sbyte.MaxValue))
					throw new ArgumentOutOfRangeException(nameof(immediate));
				instruction.InternalImmediate8 = (byte)immediate;
				break;

			case OpKind.Immediate16:
				// All short and all ushort values can be used
				if (!(short.MinValue <= immediate && immediate <= ushort.MaxValue))
					throw new ArgumentOutOfRangeException(nameof(immediate));
				instruction.InternalImmediate16 = (ushort)immediate;
				break;

			case OpKind.Immediate32:
				// All int and all uint values can be used
				if (!(int.MinValue <= immediate && immediate <= uint.MaxValue))
					throw new ArgumentOutOfRangeException(nameof(immediate));
				instruction.Immediate32 = (uint)immediate;
				break;

			case OpKind.Immediate32to64:
				if (!(int.MinValue <= immediate && immediate <= int.MaxValue))
					throw new ArgumentOutOfRangeException(nameof(immediate));
				instruction.Immediate32 = (uint)immediate;
				break;

			case OpKind.Immediate64:
				instruction.Immediate64 = (ulong)immediate;
				break;

			default:
				throw new ArgumentOutOfRangeException(nameof(opKind));
			}
		}

		static void InitializeUnsignedImmediate(ref Instruction instruction, int operand, ulong immediate) {
			var opKind = GetImmediateOpKind(instruction.Code, operand);
			instruction.SetOpKind(operand, opKind);

			switch (opKind) {
			case OpKind.Immediate8:
				if (immediate > byte.MaxValue)
					throw new ArgumentOutOfRangeException(nameof(immediate));
				instruction.InternalImmediate8 = (byte)immediate;
				break;

			case OpKind.Immediate8_2nd:
				if (immediate > byte.MaxValue)
					throw new ArgumentOutOfRangeException(nameof(immediate));
				instruction.InternalImmediate8_2nd = (byte)immediate;
				break;

			case OpKind.Immediate8to16:
				if (!(immediate <= (ulong)sbyte.MaxValue || (0xFF80 <= immediate && immediate <= 0xFFFF)))
					throw new ArgumentOutOfRangeException(nameof(immediate));
				instruction.InternalImmediate8 = (byte)immediate;
				break;

			case OpKind.Immediate8to32:
				if (!(immediate <= (ulong)sbyte.MaxValue || (0xFFFF_FF80 <= immediate && immediate <= 0xFFFF_FFFF)))
					throw new ArgumentOutOfRangeException(nameof(immediate));
				instruction.InternalImmediate8 = (byte)immediate;
				break;

			case OpKind.Immediate8to64:
				// Allow 00..7F and FFFF_FFFF_FFFF_FF80..FFFF_FFFF_FFFF_FFFF
				if ((immediate + 0x80) > byte.MaxValue)
					throw new ArgumentOutOfRangeException(nameof(immediate));
				instruction.InternalImmediate8 = (byte)immediate;
				break;

			case OpKind.Immediate16:
				if (immediate > ushort.MaxValue)
					throw new ArgumentOutOfRangeException(nameof(immediate));
				instruction.InternalImmediate16 = (ushort)immediate;
				break;

			case OpKind.Immediate32:
				if (immediate > uint.MaxValue)
					throw new ArgumentOutOfRangeException(nameof(immediate));
				instruction.Immediate32 = (uint)immediate;
				break;

			case OpKind.Immediate32to64:
				// Allow 0..7FFF_FFFF and FFFF_FFFF_8000_0000..FFFF_FFFF_FFFF_FFFF
				if ((immediate + 0x8000_0000) > (ulong)uint.MaxValue)
					throw new ArgumentOutOfRangeException(nameof(immediate));
				instruction.Immediate32 = (uint)immediate;
				break;

			case OpKind.Immediate64:
				instruction.Immediate64 = immediate;
				break;

			default:
				throw new ArgumentOutOfRangeException(nameof(opKind));
			}
		}

		static OpKind GetImmediateOpKind(Code code, int operand) {
			var handlers = EncoderInternal.OpCodeHandlers.Handlers;
			if ((uint)code >= (uint)handlers.Length)
				throw new ArgumentOutOfRangeException(nameof(code));
			var operands = handlers[(int)code].Operands;
			if ((uint)operand >= (uint)operands.Length)
				throw new ArgumentOutOfRangeException(nameof(operand), $"{code} doesn't have at least {operand + 1} operands");
			var opKind = operands[operand].GetImmediateOpKind();
			if (opKind == (OpKind)(-1))
				throw new ArgumentException($"{code}'s op{operand} isn't an immediate operand");
			return opKind;
		}

		static OpKind GetNearBranchOpKind(Code code, int operand) {
			var handlers = EncoderInternal.OpCodeHandlers.Handlers;
			if ((uint)code >= (uint)handlers.Length)
				throw new ArgumentOutOfRangeException(nameof(code));
			var operands = handlers[(int)code].Operands;
			if ((uint)operand >= (uint)operands.Length)
				throw new ArgumentOutOfRangeException(nameof(operand), $"{code} doesn't have at least {operand + 1} operands");
			var opKind = operands[operand].GetNearBranchOpKind();
			if (opKind == (OpKind)(-1))
				throw new ArgumentException($"{code}'s op{operand} isn't a near branch operand");
			return opKind;
		}

		static OpKind GetFarBranchOpKind(Code code, int operand) {
			var handlers = EncoderInternal.OpCodeHandlers.Handlers;
			if ((uint)code >= (uint)handlers.Length)
				throw new ArgumentOutOfRangeException(nameof(code));
			var operands = handlers[(int)code].Operands;
			if ((uint)operand >= (uint)operands.Length)
				throw new ArgumentOutOfRangeException(nameof(operand), $"{code} doesn't have at least {operand + 1} operands");
			var opKind = operands[operand].GetFarBranchOpKind();
			if (opKind == (OpKind)(-1))
				throw new ArgumentException($"{code}'s op{operand} isn't a far branch operand");
			return opKind;
		}

		static Instruction CreateString_Reg_SegRSI(Code code, int addressSize, Register register, Register segmentPrefix, RepPrefixKind repPrefix) {
			Instruction instruction = default;
			instruction.Code = code;

			if (repPrefix == RepPrefixKind.Repe)
				instruction.InternalSetHasRepePrefix();
			else if (repPrefix == RepPrefixKind.Repne)
				instruction.InternalSetHasRepnePrefix();
			else
				Debug.Assert(repPrefix == RepPrefixKind.None);

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp0Kind = OpKind.Register;
			instruction.InternalOp0Register = register;

			if (addressSize == 64)
				instruction.InternalOp1Kind = OpKind.MemorySegRSI;
			else if (addressSize == 32)
				instruction.InternalOp1Kind = OpKind.MemorySegESI;
			else if (addressSize == 16)
				instruction.InternalOp1Kind = OpKind.MemorySegSI;
			else
				throw new ArgumentOutOfRangeException(nameof(addressSize));

			instruction.SegmentPrefix = segmentPrefix;

			Debug.Assert(instruction.OpCount == 2);
			return instruction;
		}

		static Instruction CreateString_Reg_ESRDI(Code code, int addressSize, Register register, RepPrefixKind repPrefix) {
			Instruction instruction = default;
			instruction.Code = code;

			if (repPrefix == RepPrefixKind.Repe)
				instruction.InternalSetHasRepePrefix();
			else if (repPrefix == RepPrefixKind.Repne)
				instruction.InternalSetHasRepnePrefix();
			else
				Debug.Assert(repPrefix == RepPrefixKind.None);

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp0Kind = OpKind.Register;
			instruction.InternalOp0Register = register;

			if (addressSize == 64)
				instruction.InternalOp1Kind = OpKind.MemoryESRDI;
			else if (addressSize == 32)
				instruction.InternalOp1Kind = OpKind.MemoryESEDI;
			else if (addressSize == 16)
				instruction.InternalOp1Kind = OpKind.MemoryESDI;
			else
				throw new ArgumentOutOfRangeException(nameof(addressSize));

			Debug.Assert(instruction.OpCount == 2);
			return instruction;
		}

		static Instruction CreateString_ESRDI_Reg(Code code, int addressSize, Register register, RepPrefixKind repPrefix) {
			Instruction instruction = default;
			instruction.Code = code;

			if (repPrefix == RepPrefixKind.Repe)
				instruction.InternalSetHasRepePrefix();
			else if (repPrefix == RepPrefixKind.Repne)
				instruction.InternalSetHasRepnePrefix();
			else
				Debug.Assert(repPrefix == RepPrefixKind.None);

			if (addressSize == 64)
				instruction.InternalOp0Kind = OpKind.MemoryESRDI;
			else if (addressSize == 32)
				instruction.InternalOp0Kind = OpKind.MemoryESEDI;
			else if (addressSize == 16)
				instruction.InternalOp0Kind = OpKind.MemoryESDI;
			else
				throw new ArgumentOutOfRangeException(nameof(addressSize));

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp1Kind = OpKind.Register;
			instruction.InternalOp1Register = register;

			Debug.Assert(instruction.OpCount == 2);
			return instruction;
		}

		static Instruction CreateString_SegRSI_ESRDI(Code code, int addressSize, Register segmentPrefix, RepPrefixKind repPrefix) {
			Instruction instruction = default;
			instruction.Code = code;

			if (repPrefix == RepPrefixKind.Repe)
				instruction.InternalSetHasRepePrefix();
			else if (repPrefix == RepPrefixKind.Repne)
				instruction.InternalSetHasRepnePrefix();
			else
				Debug.Assert(repPrefix == RepPrefixKind.None);

			if (addressSize == 64) {
				instruction.InternalOp0Kind = OpKind.MemorySegRSI;
				instruction.InternalOp1Kind = OpKind.MemoryESRDI;
			}
			else if (addressSize == 32) {
				instruction.InternalOp0Kind = OpKind.MemorySegESI;
				instruction.InternalOp1Kind = OpKind.MemoryESEDI;
			}
			else if (addressSize == 16) {
				instruction.InternalOp0Kind = OpKind.MemorySegSI;
				instruction.InternalOp1Kind = OpKind.MemoryESDI;
			}
			else
				throw new ArgumentOutOfRangeException(nameof(addressSize));

			instruction.SegmentPrefix = segmentPrefix;

			Debug.Assert(instruction.OpCount == 2);
			return instruction;
		}

		static Instruction CreateString_ESRDI_SegRSI(Code code, int addressSize, Register segmentPrefix, RepPrefixKind repPrefix) {
			Instruction instruction = default;
			instruction.Code = code;

			if (repPrefix == RepPrefixKind.Repe)
				instruction.InternalSetHasRepePrefix();
			else if (repPrefix == RepPrefixKind.Repne)
				instruction.InternalSetHasRepnePrefix();
			else
				Debug.Assert(repPrefix == RepPrefixKind.None);

			if (addressSize == 64) {
				instruction.InternalOp0Kind = OpKind.MemoryESRDI;
				instruction.InternalOp1Kind = OpKind.MemorySegRSI;
			}
			else if (addressSize == 32) {
				instruction.InternalOp0Kind = OpKind.MemoryESEDI;
				instruction.InternalOp1Kind = OpKind.MemorySegESI;
			}
			else if (addressSize == 16) {
				instruction.InternalOp0Kind = OpKind.MemoryESDI;
				instruction.InternalOp1Kind = OpKind.MemorySegSI;
			}
			else
				throw new ArgumentOutOfRangeException(nameof(addressSize));

			instruction.SegmentPrefix = segmentPrefix;

			Debug.Assert(instruction.OpCount == 2);
			return instruction;
		}

		static Instruction CreateMaskmov(Code code, int addressSize, Register register1, Register register2, Register segmentPrefix) {
			Instruction instruction = default;
			instruction.Code = code;

			if (addressSize == 64)
				instruction.InternalOp0Kind = OpKind.MemorySegRDI;
			else if (addressSize == 32)
				instruction.InternalOp0Kind = OpKind.MemorySegEDI;
			else if (addressSize == 16)
				instruction.InternalOp0Kind = OpKind.MemorySegDI;
			else
				throw new ArgumentOutOfRangeException(nameof(addressSize));

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp1Kind = OpKind.Register;
			instruction.InternalOp1Register = register1;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp2Kind = OpKind.Register;
			instruction.InternalOp2Register = register2;

			instruction.SegmentPrefix = segmentPrefix;

			Debug.Assert(instruction.OpCount == 3);
			return instruction;
		}

		// GENERATOR-BEGIN: Create
		// ⚠️This was generated by GENERATOR!🦹‍♂️
		/// <summary>
		/// Creates an instruction with no operands
		/// </summary>
		/// <param name="code">Code value</param>
		public static Instruction Create(Code code) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 1 operand
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="register">op0: Register</param>
		public static Instruction Create(Code code, Register register) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp0Kind = OpKind.Register;
			instruction.InternalOp0Register = register;

			Debug.Assert(instruction.OpCount == 1);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 1 operand
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="immediate">op0: Immediate value</param>
		public static Instruction Create(Code code, int immediate) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			InitializeSignedImmediate(ref instruction, 0, immediate);

			Debug.Assert(instruction.OpCount == 1);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 1 operand
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="immediate">op0: Immediate value</param>
		public static Instruction Create(Code code, uint immediate) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			InitializeUnsignedImmediate(ref instruction, 0, immediate);

			Debug.Assert(instruction.OpCount == 1);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 1 operand
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="memory">op0: Memory operand</param>
		public static Instruction Create(Code code, in MemoryOperand memory) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			instruction.InternalOp0Kind = OpKind.Memory;
			instruction.InternalMemoryBase = memory.Base;
			instruction.InternalMemoryIndex = memory.Index;
			instruction.MemoryIndexScale = memory.Scale;
			instruction.MemoryDisplSize = memory.DisplSize;
			instruction.MemoryDisplacement = (uint)memory.Displacement;
			instruction.IsBroadcast = memory.IsBroadcast;
			instruction.SegmentPrefix = memory.SegmentPrefix;

			Debug.Assert(instruction.OpCount == 1);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 2 operands
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="register1">op0: Register</param>
		/// <param name="register2">op1: Register</param>
		public static Instruction Create(Code code, Register register1, Register register2) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp0Kind = OpKind.Register;
			instruction.InternalOp0Register = register1;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp1Kind = OpKind.Register;
			instruction.InternalOp1Register = register2;

			Debug.Assert(instruction.OpCount == 2);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 2 operands
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="register">op0: Register</param>
		/// <param name="immediate">op1: Immediate value</param>
		public static Instruction Create(Code code, Register register, int immediate) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp0Kind = OpKind.Register;
			instruction.InternalOp0Register = register;

			InitializeSignedImmediate(ref instruction, 1, immediate);

			Debug.Assert(instruction.OpCount == 2);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 2 operands
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="register">op0: Register</param>
		/// <param name="immediate">op1: Immediate value</param>
		public static Instruction Create(Code code, Register register, uint immediate) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp0Kind = OpKind.Register;
			instruction.InternalOp0Register = register;

			InitializeUnsignedImmediate(ref instruction, 1, immediate);

			Debug.Assert(instruction.OpCount == 2);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 2 operands
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="register">op0: Register</param>
		/// <param name="immediate">op1: Immediate value</param>
		public static Instruction Create(Code code, Register register, long immediate) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp0Kind = OpKind.Register;
			instruction.InternalOp0Register = register;

			InitializeSignedImmediate(ref instruction, 1, immediate);

			Debug.Assert(instruction.OpCount == 2);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 2 operands
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="register">op0: Register</param>
		/// <param name="immediate">op1: Immediate value</param>
		public static Instruction Create(Code code, Register register, ulong immediate) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp0Kind = OpKind.Register;
			instruction.InternalOp0Register = register;

			InitializeUnsignedImmediate(ref instruction, 1, immediate);

			Debug.Assert(instruction.OpCount == 2);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 2 operands
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="register">op0: Register</param>
		/// <param name="memory">op1: Memory operand</param>
		public static Instruction Create(Code code, Register register, in MemoryOperand memory) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp0Kind = OpKind.Register;
			instruction.InternalOp0Register = register;

			instruction.InternalOp1Kind = OpKind.Memory;
			instruction.InternalMemoryBase = memory.Base;
			instruction.InternalMemoryIndex = memory.Index;
			instruction.MemoryIndexScale = memory.Scale;
			instruction.MemoryDisplSize = memory.DisplSize;
			instruction.MemoryDisplacement = (uint)memory.Displacement;
			instruction.IsBroadcast = memory.IsBroadcast;
			instruction.SegmentPrefix = memory.SegmentPrefix;

			Debug.Assert(instruction.OpCount == 2);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 2 operands
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="immediate">op0: Immediate value</param>
		/// <param name="register">op1: Register</param>
		public static Instruction Create(Code code, int immediate, Register register) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			InitializeSignedImmediate(ref instruction, 0, immediate);

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp1Kind = OpKind.Register;
			instruction.InternalOp1Register = register;

			Debug.Assert(instruction.OpCount == 2);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 2 operands
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="immediate">op0: Immediate value</param>
		/// <param name="register">op1: Register</param>
		public static Instruction Create(Code code, uint immediate, Register register) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			InitializeUnsignedImmediate(ref instruction, 0, immediate);

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp1Kind = OpKind.Register;
			instruction.InternalOp1Register = register;

			Debug.Assert(instruction.OpCount == 2);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 2 operands
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="immediate1">op0: Immediate value</param>
		/// <param name="immediate2">op1: Immediate value</param>
		public static Instruction Create(Code code, int immediate1, int immediate2) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			InitializeSignedImmediate(ref instruction, 0, immediate1);

			InitializeSignedImmediate(ref instruction, 1, immediate2);

			Debug.Assert(instruction.OpCount == 2);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 2 operands
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="immediate1">op0: Immediate value</param>
		/// <param name="immediate2">op1: Immediate value</param>
		public static Instruction Create(Code code, uint immediate1, uint immediate2) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			InitializeUnsignedImmediate(ref instruction, 0, immediate1);

			InitializeUnsignedImmediate(ref instruction, 1, immediate2);

			Debug.Assert(instruction.OpCount == 2);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 2 operands
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="memory">op0: Memory operand</param>
		/// <param name="register">op1: Register</param>
		public static Instruction Create(Code code, in MemoryOperand memory, Register register) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			instruction.InternalOp0Kind = OpKind.Memory;
			instruction.InternalMemoryBase = memory.Base;
			instruction.InternalMemoryIndex = memory.Index;
			instruction.MemoryIndexScale = memory.Scale;
			instruction.MemoryDisplSize = memory.DisplSize;
			instruction.MemoryDisplacement = (uint)memory.Displacement;
			instruction.IsBroadcast = memory.IsBroadcast;
			instruction.SegmentPrefix = memory.SegmentPrefix;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp1Kind = OpKind.Register;
			instruction.InternalOp1Register = register;

			Debug.Assert(instruction.OpCount == 2);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 2 operands
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="memory">op0: Memory operand</param>
		/// <param name="immediate">op1: Immediate value</param>
		public static Instruction Create(Code code, in MemoryOperand memory, int immediate) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			instruction.InternalOp0Kind = OpKind.Memory;
			instruction.InternalMemoryBase = memory.Base;
			instruction.InternalMemoryIndex = memory.Index;
			instruction.MemoryIndexScale = memory.Scale;
			instruction.MemoryDisplSize = memory.DisplSize;
			instruction.MemoryDisplacement = (uint)memory.Displacement;
			instruction.IsBroadcast = memory.IsBroadcast;
			instruction.SegmentPrefix = memory.SegmentPrefix;

			InitializeSignedImmediate(ref instruction, 1, immediate);

			Debug.Assert(instruction.OpCount == 2);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 2 operands
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="memory">op0: Memory operand</param>
		/// <param name="immediate">op1: Immediate value</param>
		public static Instruction Create(Code code, in MemoryOperand memory, uint immediate) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			instruction.InternalOp0Kind = OpKind.Memory;
			instruction.InternalMemoryBase = memory.Base;
			instruction.InternalMemoryIndex = memory.Index;
			instruction.MemoryIndexScale = memory.Scale;
			instruction.MemoryDisplSize = memory.DisplSize;
			instruction.MemoryDisplacement = (uint)memory.Displacement;
			instruction.IsBroadcast = memory.IsBroadcast;
			instruction.SegmentPrefix = memory.SegmentPrefix;

			InitializeUnsignedImmediate(ref instruction, 1, immediate);

			Debug.Assert(instruction.OpCount == 2);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 3 operands
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="register1">op0: Register</param>
		/// <param name="register2">op1: Register</param>
		/// <param name="register3">op2: Register</param>
		public static Instruction Create(Code code, Register register1, Register register2, Register register3) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp0Kind = OpKind.Register;
			instruction.InternalOp0Register = register1;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp1Kind = OpKind.Register;
			instruction.InternalOp1Register = register2;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp2Kind = OpKind.Register;
			instruction.InternalOp2Register = register3;

			Debug.Assert(instruction.OpCount == 3);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 3 operands
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="register1">op0: Register</param>
		/// <param name="register2">op1: Register</param>
		/// <param name="immediate">op2: Immediate value</param>
		public static Instruction Create(Code code, Register register1, Register register2, int immediate) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp0Kind = OpKind.Register;
			instruction.InternalOp0Register = register1;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp1Kind = OpKind.Register;
			instruction.InternalOp1Register = register2;

			InitializeSignedImmediate(ref instruction, 2, immediate);

			Debug.Assert(instruction.OpCount == 3);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 3 operands
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="register1">op0: Register</param>
		/// <param name="register2">op1: Register</param>
		/// <param name="immediate">op2: Immediate value</param>
		public static Instruction Create(Code code, Register register1, Register register2, uint immediate) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp0Kind = OpKind.Register;
			instruction.InternalOp0Register = register1;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp1Kind = OpKind.Register;
			instruction.InternalOp1Register = register2;

			InitializeUnsignedImmediate(ref instruction, 2, immediate);

			Debug.Assert(instruction.OpCount == 3);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 3 operands
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="register1">op0: Register</param>
		/// <param name="register2">op1: Register</param>
		/// <param name="memory">op2: Memory operand</param>
		public static Instruction Create(Code code, Register register1, Register register2, in MemoryOperand memory) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp0Kind = OpKind.Register;
			instruction.InternalOp0Register = register1;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp1Kind = OpKind.Register;
			instruction.InternalOp1Register = register2;

			instruction.InternalOp2Kind = OpKind.Memory;
			instruction.InternalMemoryBase = memory.Base;
			instruction.InternalMemoryIndex = memory.Index;
			instruction.MemoryIndexScale = memory.Scale;
			instruction.MemoryDisplSize = memory.DisplSize;
			instruction.MemoryDisplacement = (uint)memory.Displacement;
			instruction.IsBroadcast = memory.IsBroadcast;
			instruction.SegmentPrefix = memory.SegmentPrefix;

			Debug.Assert(instruction.OpCount == 3);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 3 operands
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="register">op0: Register</param>
		/// <param name="immediate1">op1: Immediate value</param>
		/// <param name="immediate2">op2: Immediate value</param>
		public static Instruction Create(Code code, Register register, int immediate1, int immediate2) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp0Kind = OpKind.Register;
			instruction.InternalOp0Register = register;

			InitializeSignedImmediate(ref instruction, 1, immediate1);

			InitializeSignedImmediate(ref instruction, 2, immediate2);

			Debug.Assert(instruction.OpCount == 3);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 3 operands
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="register">op0: Register</param>
		/// <param name="immediate1">op1: Immediate value</param>
		/// <param name="immediate2">op2: Immediate value</param>
		public static Instruction Create(Code code, Register register, uint immediate1, uint immediate2) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp0Kind = OpKind.Register;
			instruction.InternalOp0Register = register;

			InitializeUnsignedImmediate(ref instruction, 1, immediate1);

			InitializeUnsignedImmediate(ref instruction, 2, immediate2);

			Debug.Assert(instruction.OpCount == 3);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 3 operands
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="register1">op0: Register</param>
		/// <param name="memory">op1: Memory operand</param>
		/// <param name="register2">op2: Register</param>
		public static Instruction Create(Code code, Register register1, in MemoryOperand memory, Register register2) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp0Kind = OpKind.Register;
			instruction.InternalOp0Register = register1;

			instruction.InternalOp1Kind = OpKind.Memory;
			instruction.InternalMemoryBase = memory.Base;
			instruction.InternalMemoryIndex = memory.Index;
			instruction.MemoryIndexScale = memory.Scale;
			instruction.MemoryDisplSize = memory.DisplSize;
			instruction.MemoryDisplacement = (uint)memory.Displacement;
			instruction.IsBroadcast = memory.IsBroadcast;
			instruction.SegmentPrefix = memory.SegmentPrefix;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp2Kind = OpKind.Register;
			instruction.InternalOp2Register = register2;

			Debug.Assert(instruction.OpCount == 3);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 3 operands
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="register">op0: Register</param>
		/// <param name="memory">op1: Memory operand</param>
		/// <param name="immediate">op2: Immediate value</param>
		public static Instruction Create(Code code, Register register, in MemoryOperand memory, int immediate) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp0Kind = OpKind.Register;
			instruction.InternalOp0Register = register;

			instruction.InternalOp1Kind = OpKind.Memory;
			instruction.InternalMemoryBase = memory.Base;
			instruction.InternalMemoryIndex = memory.Index;
			instruction.MemoryIndexScale = memory.Scale;
			instruction.MemoryDisplSize = memory.DisplSize;
			instruction.MemoryDisplacement = (uint)memory.Displacement;
			instruction.IsBroadcast = memory.IsBroadcast;
			instruction.SegmentPrefix = memory.SegmentPrefix;

			InitializeSignedImmediate(ref instruction, 2, immediate);

			Debug.Assert(instruction.OpCount == 3);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 3 operands
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="register">op0: Register</param>
		/// <param name="memory">op1: Memory operand</param>
		/// <param name="immediate">op2: Immediate value</param>
		public static Instruction Create(Code code, Register register, in MemoryOperand memory, uint immediate) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp0Kind = OpKind.Register;
			instruction.InternalOp0Register = register;

			instruction.InternalOp1Kind = OpKind.Memory;
			instruction.InternalMemoryBase = memory.Base;
			instruction.InternalMemoryIndex = memory.Index;
			instruction.MemoryIndexScale = memory.Scale;
			instruction.MemoryDisplSize = memory.DisplSize;
			instruction.MemoryDisplacement = (uint)memory.Displacement;
			instruction.IsBroadcast = memory.IsBroadcast;
			instruction.SegmentPrefix = memory.SegmentPrefix;

			InitializeUnsignedImmediate(ref instruction, 2, immediate);

			Debug.Assert(instruction.OpCount == 3);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 3 operands
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="memory">op0: Memory operand</param>
		/// <param name="register1">op1: Register</param>
		/// <param name="register2">op2: Register</param>
		public static Instruction Create(Code code, in MemoryOperand memory, Register register1, Register register2) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			instruction.InternalOp0Kind = OpKind.Memory;
			instruction.InternalMemoryBase = memory.Base;
			instruction.InternalMemoryIndex = memory.Index;
			instruction.MemoryIndexScale = memory.Scale;
			instruction.MemoryDisplSize = memory.DisplSize;
			instruction.MemoryDisplacement = (uint)memory.Displacement;
			instruction.IsBroadcast = memory.IsBroadcast;
			instruction.SegmentPrefix = memory.SegmentPrefix;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp1Kind = OpKind.Register;
			instruction.InternalOp1Register = register1;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp2Kind = OpKind.Register;
			instruction.InternalOp2Register = register2;

			Debug.Assert(instruction.OpCount == 3);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 3 operands
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="memory">op0: Memory operand</param>
		/// <param name="register">op1: Register</param>
		/// <param name="immediate">op2: Immediate value</param>
		public static Instruction Create(Code code, in MemoryOperand memory, Register register, int immediate) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			instruction.InternalOp0Kind = OpKind.Memory;
			instruction.InternalMemoryBase = memory.Base;
			instruction.InternalMemoryIndex = memory.Index;
			instruction.MemoryIndexScale = memory.Scale;
			instruction.MemoryDisplSize = memory.DisplSize;
			instruction.MemoryDisplacement = (uint)memory.Displacement;
			instruction.IsBroadcast = memory.IsBroadcast;
			instruction.SegmentPrefix = memory.SegmentPrefix;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp1Kind = OpKind.Register;
			instruction.InternalOp1Register = register;

			InitializeSignedImmediate(ref instruction, 2, immediate);

			Debug.Assert(instruction.OpCount == 3);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 3 operands
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="memory">op0: Memory operand</param>
		/// <param name="register">op1: Register</param>
		/// <param name="immediate">op2: Immediate value</param>
		public static Instruction Create(Code code, in MemoryOperand memory, Register register, uint immediate) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			instruction.InternalOp0Kind = OpKind.Memory;
			instruction.InternalMemoryBase = memory.Base;
			instruction.InternalMemoryIndex = memory.Index;
			instruction.MemoryIndexScale = memory.Scale;
			instruction.MemoryDisplSize = memory.DisplSize;
			instruction.MemoryDisplacement = (uint)memory.Displacement;
			instruction.IsBroadcast = memory.IsBroadcast;
			instruction.SegmentPrefix = memory.SegmentPrefix;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp1Kind = OpKind.Register;
			instruction.InternalOp1Register = register;

			InitializeUnsignedImmediate(ref instruction, 2, immediate);

			Debug.Assert(instruction.OpCount == 3);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 4 operands
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="register1">op0: Register</param>
		/// <param name="register2">op1: Register</param>
		/// <param name="register3">op2: Register</param>
		/// <param name="register4">op3: Register</param>
		public static Instruction Create(Code code, Register register1, Register register2, Register register3, Register register4) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp0Kind = OpKind.Register;
			instruction.InternalOp0Register = register1;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp1Kind = OpKind.Register;
			instruction.InternalOp1Register = register2;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp2Kind = OpKind.Register;
			instruction.InternalOp2Register = register3;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp3Kind = OpKind.Register;
			instruction.InternalOp3Register = register4;

			Debug.Assert(instruction.OpCount == 4);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 4 operands
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="register1">op0: Register</param>
		/// <param name="register2">op1: Register</param>
		/// <param name="register3">op2: Register</param>
		/// <param name="immediate">op3: Immediate value</param>
		public static Instruction Create(Code code, Register register1, Register register2, Register register3, int immediate) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp0Kind = OpKind.Register;
			instruction.InternalOp0Register = register1;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp1Kind = OpKind.Register;
			instruction.InternalOp1Register = register2;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp2Kind = OpKind.Register;
			instruction.InternalOp2Register = register3;

			InitializeSignedImmediate(ref instruction, 3, immediate);

			Debug.Assert(instruction.OpCount == 4);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 4 operands
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="register1">op0: Register</param>
		/// <param name="register2">op1: Register</param>
		/// <param name="register3">op2: Register</param>
		/// <param name="immediate">op3: Immediate value</param>
		public static Instruction Create(Code code, Register register1, Register register2, Register register3, uint immediate) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp0Kind = OpKind.Register;
			instruction.InternalOp0Register = register1;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp1Kind = OpKind.Register;
			instruction.InternalOp1Register = register2;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp2Kind = OpKind.Register;
			instruction.InternalOp2Register = register3;

			InitializeUnsignedImmediate(ref instruction, 3, immediate);

			Debug.Assert(instruction.OpCount == 4);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 4 operands
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="register1">op0: Register</param>
		/// <param name="register2">op1: Register</param>
		/// <param name="register3">op2: Register</param>
		/// <param name="memory">op3: Memory operand</param>
		public static Instruction Create(Code code, Register register1, Register register2, Register register3, in MemoryOperand memory) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp0Kind = OpKind.Register;
			instruction.InternalOp0Register = register1;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp1Kind = OpKind.Register;
			instruction.InternalOp1Register = register2;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp2Kind = OpKind.Register;
			instruction.InternalOp2Register = register3;

			instruction.InternalOp3Kind = OpKind.Memory;
			instruction.InternalMemoryBase = memory.Base;
			instruction.InternalMemoryIndex = memory.Index;
			instruction.MemoryIndexScale = memory.Scale;
			instruction.MemoryDisplSize = memory.DisplSize;
			instruction.MemoryDisplacement = (uint)memory.Displacement;
			instruction.IsBroadcast = memory.IsBroadcast;
			instruction.SegmentPrefix = memory.SegmentPrefix;

			Debug.Assert(instruction.OpCount == 4);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 4 operands
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="register1">op0: Register</param>
		/// <param name="register2">op1: Register</param>
		/// <param name="immediate1">op2: Immediate value</param>
		/// <param name="immediate2">op3: Immediate value</param>
		public static Instruction Create(Code code, Register register1, Register register2, int immediate1, int immediate2) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp0Kind = OpKind.Register;
			instruction.InternalOp0Register = register1;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp1Kind = OpKind.Register;
			instruction.InternalOp1Register = register2;

			InitializeSignedImmediate(ref instruction, 2, immediate1);

			InitializeSignedImmediate(ref instruction, 3, immediate2);

			Debug.Assert(instruction.OpCount == 4);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 4 operands
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="register1">op0: Register</param>
		/// <param name="register2">op1: Register</param>
		/// <param name="immediate1">op2: Immediate value</param>
		/// <param name="immediate2">op3: Immediate value</param>
		public static Instruction Create(Code code, Register register1, Register register2, uint immediate1, uint immediate2) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp0Kind = OpKind.Register;
			instruction.InternalOp0Register = register1;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp1Kind = OpKind.Register;
			instruction.InternalOp1Register = register2;

			InitializeUnsignedImmediate(ref instruction, 2, immediate1);

			InitializeUnsignedImmediate(ref instruction, 3, immediate2);

			Debug.Assert(instruction.OpCount == 4);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 4 operands
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="register1">op0: Register</param>
		/// <param name="register2">op1: Register</param>
		/// <param name="memory">op2: Memory operand</param>
		/// <param name="register3">op3: Register</param>
		public static Instruction Create(Code code, Register register1, Register register2, in MemoryOperand memory, Register register3) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp0Kind = OpKind.Register;
			instruction.InternalOp0Register = register1;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp1Kind = OpKind.Register;
			instruction.InternalOp1Register = register2;

			instruction.InternalOp2Kind = OpKind.Memory;
			instruction.InternalMemoryBase = memory.Base;
			instruction.InternalMemoryIndex = memory.Index;
			instruction.MemoryIndexScale = memory.Scale;
			instruction.MemoryDisplSize = memory.DisplSize;
			instruction.MemoryDisplacement = (uint)memory.Displacement;
			instruction.IsBroadcast = memory.IsBroadcast;
			instruction.SegmentPrefix = memory.SegmentPrefix;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp3Kind = OpKind.Register;
			instruction.InternalOp3Register = register3;

			Debug.Assert(instruction.OpCount == 4);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 4 operands
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="register1">op0: Register</param>
		/// <param name="register2">op1: Register</param>
		/// <param name="memory">op2: Memory operand</param>
		/// <param name="immediate">op3: Immediate value</param>
		public static Instruction Create(Code code, Register register1, Register register2, in MemoryOperand memory, int immediate) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp0Kind = OpKind.Register;
			instruction.InternalOp0Register = register1;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp1Kind = OpKind.Register;
			instruction.InternalOp1Register = register2;

			instruction.InternalOp2Kind = OpKind.Memory;
			instruction.InternalMemoryBase = memory.Base;
			instruction.InternalMemoryIndex = memory.Index;
			instruction.MemoryIndexScale = memory.Scale;
			instruction.MemoryDisplSize = memory.DisplSize;
			instruction.MemoryDisplacement = (uint)memory.Displacement;
			instruction.IsBroadcast = memory.IsBroadcast;
			instruction.SegmentPrefix = memory.SegmentPrefix;

			InitializeSignedImmediate(ref instruction, 3, immediate);

			Debug.Assert(instruction.OpCount == 4);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 4 operands
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="register1">op0: Register</param>
		/// <param name="register2">op1: Register</param>
		/// <param name="memory">op2: Memory operand</param>
		/// <param name="immediate">op3: Immediate value</param>
		public static Instruction Create(Code code, Register register1, Register register2, in MemoryOperand memory, uint immediate) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp0Kind = OpKind.Register;
			instruction.InternalOp0Register = register1;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp1Kind = OpKind.Register;
			instruction.InternalOp1Register = register2;

			instruction.InternalOp2Kind = OpKind.Memory;
			instruction.InternalMemoryBase = memory.Base;
			instruction.InternalMemoryIndex = memory.Index;
			instruction.MemoryIndexScale = memory.Scale;
			instruction.MemoryDisplSize = memory.DisplSize;
			instruction.MemoryDisplacement = (uint)memory.Displacement;
			instruction.IsBroadcast = memory.IsBroadcast;
			instruction.SegmentPrefix = memory.SegmentPrefix;

			InitializeUnsignedImmediate(ref instruction, 3, immediate);

			Debug.Assert(instruction.OpCount == 4);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 5 operands
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="register1">op0: Register</param>
		/// <param name="register2">op1: Register</param>
		/// <param name="register3">op2: Register</param>
		/// <param name="register4">op3: Register</param>
		/// <param name="immediate">op4: Immediate value</param>
		public static Instruction Create(Code code, Register register1, Register register2, Register register3, Register register4, int immediate) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp0Kind = OpKind.Register;
			instruction.InternalOp0Register = register1;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp1Kind = OpKind.Register;
			instruction.InternalOp1Register = register2;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp2Kind = OpKind.Register;
			instruction.InternalOp2Register = register3;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp3Kind = OpKind.Register;
			instruction.InternalOp3Register = register4;

			InitializeSignedImmediate(ref instruction, 4, immediate);

			Debug.Assert(instruction.OpCount == 5);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 5 operands
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="register1">op0: Register</param>
		/// <param name="register2">op1: Register</param>
		/// <param name="register3">op2: Register</param>
		/// <param name="register4">op3: Register</param>
		/// <param name="immediate">op4: Immediate value</param>
		public static Instruction Create(Code code, Register register1, Register register2, Register register3, Register register4, uint immediate) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp0Kind = OpKind.Register;
			instruction.InternalOp0Register = register1;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp1Kind = OpKind.Register;
			instruction.InternalOp1Register = register2;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp2Kind = OpKind.Register;
			instruction.InternalOp2Register = register3;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp3Kind = OpKind.Register;
			instruction.InternalOp3Register = register4;

			InitializeUnsignedImmediate(ref instruction, 4, immediate);

			Debug.Assert(instruction.OpCount == 5);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 5 operands
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="register1">op0: Register</param>
		/// <param name="register2">op1: Register</param>
		/// <param name="register3">op2: Register</param>
		/// <param name="memory">op3: Memory operand</param>
		/// <param name="immediate">op4: Immediate value</param>
		public static Instruction Create(Code code, Register register1, Register register2, Register register3, in MemoryOperand memory, int immediate) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp0Kind = OpKind.Register;
			instruction.InternalOp0Register = register1;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp1Kind = OpKind.Register;
			instruction.InternalOp1Register = register2;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp2Kind = OpKind.Register;
			instruction.InternalOp2Register = register3;

			instruction.InternalOp3Kind = OpKind.Memory;
			instruction.InternalMemoryBase = memory.Base;
			instruction.InternalMemoryIndex = memory.Index;
			instruction.MemoryIndexScale = memory.Scale;
			instruction.MemoryDisplSize = memory.DisplSize;
			instruction.MemoryDisplacement = (uint)memory.Displacement;
			instruction.IsBroadcast = memory.IsBroadcast;
			instruction.SegmentPrefix = memory.SegmentPrefix;

			InitializeSignedImmediate(ref instruction, 4, immediate);

			Debug.Assert(instruction.OpCount == 5);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 5 operands
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="register1">op0: Register</param>
		/// <param name="register2">op1: Register</param>
		/// <param name="register3">op2: Register</param>
		/// <param name="memory">op3: Memory operand</param>
		/// <param name="immediate">op4: Immediate value</param>
		public static Instruction Create(Code code, Register register1, Register register2, Register register3, in MemoryOperand memory, uint immediate) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp0Kind = OpKind.Register;
			instruction.InternalOp0Register = register1;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp1Kind = OpKind.Register;
			instruction.InternalOp1Register = register2;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp2Kind = OpKind.Register;
			instruction.InternalOp2Register = register3;

			instruction.InternalOp3Kind = OpKind.Memory;
			instruction.InternalMemoryBase = memory.Base;
			instruction.InternalMemoryIndex = memory.Index;
			instruction.MemoryIndexScale = memory.Scale;
			instruction.MemoryDisplSize = memory.DisplSize;
			instruction.MemoryDisplacement = (uint)memory.Displacement;
			instruction.IsBroadcast = memory.IsBroadcast;
			instruction.SegmentPrefix = memory.SegmentPrefix;

			InitializeUnsignedImmediate(ref instruction, 4, immediate);

			Debug.Assert(instruction.OpCount == 5);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 5 operands
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="register1">op0: Register</param>
		/// <param name="register2">op1: Register</param>
		/// <param name="memory">op2: Memory operand</param>
		/// <param name="register3">op3: Register</param>
		/// <param name="immediate">op4: Immediate value</param>
		public static Instruction Create(Code code, Register register1, Register register2, in MemoryOperand memory, Register register3, int immediate) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp0Kind = OpKind.Register;
			instruction.InternalOp0Register = register1;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp1Kind = OpKind.Register;
			instruction.InternalOp1Register = register2;

			instruction.InternalOp2Kind = OpKind.Memory;
			instruction.InternalMemoryBase = memory.Base;
			instruction.InternalMemoryIndex = memory.Index;
			instruction.MemoryIndexScale = memory.Scale;
			instruction.MemoryDisplSize = memory.DisplSize;
			instruction.MemoryDisplacement = (uint)memory.Displacement;
			instruction.IsBroadcast = memory.IsBroadcast;
			instruction.SegmentPrefix = memory.SegmentPrefix;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp3Kind = OpKind.Register;
			instruction.InternalOp3Register = register3;

			InitializeSignedImmediate(ref instruction, 4, immediate);

			Debug.Assert(instruction.OpCount == 5);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with 5 operands
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="register1">op0: Register</param>
		/// <param name="register2">op1: Register</param>
		/// <param name="memory">op2: Memory operand</param>
		/// <param name="register3">op3: Register</param>
		/// <param name="immediate">op4: Immediate value</param>
		public static Instruction Create(Code code, Register register1, Register register2, in MemoryOperand memory, Register register3, uint immediate) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp0Kind = OpKind.Register;
			instruction.InternalOp0Register = register1;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp1Kind = OpKind.Register;
			instruction.InternalOp1Register = register2;

			instruction.InternalOp2Kind = OpKind.Memory;
			instruction.InternalMemoryBase = memory.Base;
			instruction.InternalMemoryIndex = memory.Index;
			instruction.MemoryIndexScale = memory.Scale;
			instruction.MemoryDisplSize = memory.DisplSize;
			instruction.MemoryDisplacement = (uint)memory.Displacement;
			instruction.IsBroadcast = memory.IsBroadcast;
			instruction.SegmentPrefix = memory.SegmentPrefix;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp3Kind = OpKind.Register;
			instruction.InternalOp3Register = register3;

			InitializeUnsignedImmediate(ref instruction, 4, immediate);

			Debug.Assert(instruction.OpCount == 5);
			return instruction;
		}

		/// <summary>
		/// Creates a new near/short branch instruction
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="target">Target address</param>
		public static Instruction CreateBranch(Code code, ulong target) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			instruction.InternalOp0Kind = GetNearBranchOpKind(code, 0);
			instruction.NearBranch64 = target;

			Debug.Assert(instruction.OpCount == 1);
			return instruction;
		}

		/// <summary>
		/// Creates a new far branch instruction
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="selector">Selector/segment value</param>
		/// <param name="offset">Offset</param>
		public static Instruction CreateBranch(Code code, ushort selector, uint offset) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			instruction.InternalOp0Kind = GetFarBranchOpKind(code, 0);
			instruction.FarBranchSelector = selector;
			instruction.FarBranch32 = offset;

			Debug.Assert(instruction.OpCount == 1);
			return instruction;
		}

		/// <summary>
		/// Creates a new <c>XBEGIN</c> instruction
		/// </summary>
		/// <param name="bitness">16, 32, or 64</param>
		/// <param name="target">Target address</param>
		public static Instruction CreateXbegin(int bitness, ulong target) {
			Instruction instruction = default;
			switch (bitness) {
			case 16:
				instruction.InternalCode = Code.Xbegin_rel16;
				instruction.InternalOp0Kind = OpKind.NearBranch32;
				instruction.NearBranch32 = (uint)target;
				break;

			case 32:
				instruction.InternalCode = Code.Xbegin_rel32;
				instruction.InternalOp0Kind = OpKind.NearBranch32;
				instruction.NearBranch32 = (uint)target;
				break;

			case 64:
				instruction.InternalCode = Code.Xbegin_rel32;
				instruction.InternalOp0Kind = OpKind.NearBranch64;
				instruction.NearBranch64 = target;
				break;

			default:
				throw new ArgumentOutOfRangeException(nameof(bitness));
			}

			Debug.Assert(instruction.OpCount == 1);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with a 64-bit memory offset as the second operand, eg. <c>mov al,[123456789ABCDEF0]</c>
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="register">Register (<c>AL</c>, <c>AX</c>, <c>EAX</c>, <c>RAX</c>)</param>
		/// <param name="address">64-bit address</param>
		/// <param name="segmentPrefix">Segment override or <see cref="Register.None"/></param>
		public static Instruction CreateMemory64(Code code, Register register, ulong address, Register segmentPrefix = Register.None) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			instruction.InternalOp1Kind = OpKind.Memory64;
			instruction.MemoryAddress64 = address;
			instruction.InternalSetMemoryDisplSize(4);
			instruction.SegmentPrefix = segmentPrefix;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp0Kind = OpKind.Register;
			instruction.InternalOp0Register = register;

			Debug.Assert(instruction.OpCount == 2);
			return instruction;
		}

		/// <summary>
		/// Creates an instruction with a 64-bit memory offset as the first operand, eg. <c>mov [123456789ABCDEF0],al</c>
		/// </summary>
		/// <param name="code">Code value</param>
		/// <param name="address">64-bit address</param>
		/// <param name="register">Register (<c>AL</c>, <c>AX</c>, <c>EAX</c>, <c>RAX</c>)</param>
		/// <param name="segmentPrefix">Segment override or <see cref="Register.None"/></param>
		public static Instruction CreateMemory64(Code code, ulong address, Register register, Register segmentPrefix = Register.None) {
			Instruction instruction = default;
			instruction.InternalCode = code;

			instruction.InternalOp0Kind = OpKind.Memory64;
			instruction.MemoryAddress64 = address;
			instruction.InternalSetMemoryDisplSize(4);
			instruction.SegmentPrefix = segmentPrefix;

			Static.Assert(OpKind.Register == 0 ? 0 : -1);
			//instruction.InternalOp1Kind = OpKind.Register;
			instruction.InternalOp1Register = register;

			Debug.Assert(instruction.OpCount == 2);
			return instruction;
		}

		/// <summary>
		/// Creates a <c>OUTSB</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		/// <param name="segmentPrefix">Segment override or <see cref="Register.None"/></param>
		/// <param name="repPrefix">Rep prefix or <see cref="RepPrefixKind.None"/></param>
		public static Instruction CreateOutsb(int addressSize, Register segmentPrefix = Register.None, RepPrefixKind repPrefix = RepPrefixKind.None) =>
			CreateString_Reg_SegRSI(Code.Outsb_DX_m8, addressSize, Register.DX, segmentPrefix, repPrefix);

		/// <summary>
		/// Creates a <c>REP OUTSB</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		public static Instruction CreateRepOutsb(int addressSize) =>
			CreateString_Reg_SegRSI(Code.Outsb_DX_m8, addressSize, Register.DX, Register.None, RepPrefixKind.Repe);

		/// <summary>
		/// Creates a <c>OUTSW</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		/// <param name="segmentPrefix">Segment override or <see cref="Register.None"/></param>
		/// <param name="repPrefix">Rep prefix or <see cref="RepPrefixKind.None"/></param>
		public static Instruction CreateOutsw(int addressSize, Register segmentPrefix = Register.None, RepPrefixKind repPrefix = RepPrefixKind.None) =>
			CreateString_Reg_SegRSI(Code.Outsw_DX_m16, addressSize, Register.DX, segmentPrefix, repPrefix);

		/// <summary>
		/// Creates a <c>REP OUTSW</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		public static Instruction CreateRepOutsw(int addressSize) =>
			CreateString_Reg_SegRSI(Code.Outsw_DX_m16, addressSize, Register.DX, Register.None, RepPrefixKind.Repe);

		/// <summary>
		/// Creates a <c>OUTSD</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		/// <param name="segmentPrefix">Segment override or <see cref="Register.None"/></param>
		/// <param name="repPrefix">Rep prefix or <see cref="RepPrefixKind.None"/></param>
		public static Instruction CreateOutsd(int addressSize, Register segmentPrefix = Register.None, RepPrefixKind repPrefix = RepPrefixKind.None) =>
			CreateString_Reg_SegRSI(Code.Outsd_DX_m32, addressSize, Register.DX, segmentPrefix, repPrefix);

		/// <summary>
		/// Creates a <c>REP OUTSD</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		public static Instruction CreateRepOutsd(int addressSize) =>
			CreateString_Reg_SegRSI(Code.Outsd_DX_m32, addressSize, Register.DX, Register.None, RepPrefixKind.Repe);

		/// <summary>
		/// Creates a <c>LODSB</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		/// <param name="segmentPrefix">Segment override or <see cref="Register.None"/></param>
		/// <param name="repPrefix">Rep prefix or <see cref="RepPrefixKind.None"/></param>
		public static Instruction CreateLodsb(int addressSize, Register segmentPrefix = Register.None, RepPrefixKind repPrefix = RepPrefixKind.None) =>
			CreateString_Reg_SegRSI(Code.Lodsb_AL_m8, addressSize, Register.AL, segmentPrefix, repPrefix);

		/// <summary>
		/// Creates a <c>REP LODSB</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		public static Instruction CreateRepLodsb(int addressSize) =>
			CreateString_Reg_SegRSI(Code.Lodsb_AL_m8, addressSize, Register.AL, Register.None, RepPrefixKind.Repe);

		/// <summary>
		/// Creates a <c>LODSW</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		/// <param name="segmentPrefix">Segment override or <see cref="Register.None"/></param>
		/// <param name="repPrefix">Rep prefix or <see cref="RepPrefixKind.None"/></param>
		public static Instruction CreateLodsw(int addressSize, Register segmentPrefix = Register.None, RepPrefixKind repPrefix = RepPrefixKind.None) =>
			CreateString_Reg_SegRSI(Code.Lodsw_AX_m16, addressSize, Register.AX, segmentPrefix, repPrefix);

		/// <summary>
		/// Creates a <c>REP LODSW</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		public static Instruction CreateRepLodsw(int addressSize) =>
			CreateString_Reg_SegRSI(Code.Lodsw_AX_m16, addressSize, Register.AX, Register.None, RepPrefixKind.Repe);

		/// <summary>
		/// Creates a <c>LODSD</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		/// <param name="segmentPrefix">Segment override or <see cref="Register.None"/></param>
		/// <param name="repPrefix">Rep prefix or <see cref="RepPrefixKind.None"/></param>
		public static Instruction CreateLodsd(int addressSize, Register segmentPrefix = Register.None, RepPrefixKind repPrefix = RepPrefixKind.None) =>
			CreateString_Reg_SegRSI(Code.Lodsd_EAX_m32, addressSize, Register.EAX, segmentPrefix, repPrefix);

		/// <summary>
		/// Creates a <c>REP LODSD</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		public static Instruction CreateRepLodsd(int addressSize) =>
			CreateString_Reg_SegRSI(Code.Lodsd_EAX_m32, addressSize, Register.EAX, Register.None, RepPrefixKind.Repe);

		/// <summary>
		/// Creates a <c>LODSQ</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		/// <param name="segmentPrefix">Segment override or <see cref="Register.None"/></param>
		/// <param name="repPrefix">Rep prefix or <see cref="RepPrefixKind.None"/></param>
		public static Instruction CreateLodsq(int addressSize, Register segmentPrefix = Register.None, RepPrefixKind repPrefix = RepPrefixKind.None) =>
			CreateString_Reg_SegRSI(Code.Lodsq_RAX_m64, addressSize, Register.RAX, segmentPrefix, repPrefix);

		/// <summary>
		/// Creates a <c>REP LODSQ</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		public static Instruction CreateRepLodsq(int addressSize) =>
			CreateString_Reg_SegRSI(Code.Lodsq_RAX_m64, addressSize, Register.RAX, Register.None, RepPrefixKind.Repe);

		/// <summary>
		/// Creates a <c>SCASB</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		/// <param name="repPrefix">Rep prefix or <see cref="RepPrefixKind.None"/></param>
		public static Instruction CreateScasb(int addressSize, RepPrefixKind repPrefix = RepPrefixKind.None) =>
			CreateString_Reg_ESRDI(Code.Scasb_AL_m8, addressSize, Register.AL, repPrefix);

		/// <summary>
		/// Creates a <c>REPE SCASB</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		public static Instruction CreateRepeScasb(int addressSize) =>
			CreateString_Reg_ESRDI(Code.Scasb_AL_m8, addressSize, Register.AL, RepPrefixKind.Repe);

		/// <summary>
		/// Creates a <c>REPNE SCASB</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		public static Instruction CreateRepneScasb(int addressSize) =>
			CreateString_Reg_ESRDI(Code.Scasb_AL_m8, addressSize, Register.AL, RepPrefixKind.Repne);

		/// <summary>
		/// Creates a <c>SCASW</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		/// <param name="repPrefix">Rep prefix or <see cref="RepPrefixKind.None"/></param>
		public static Instruction CreateScasw(int addressSize, RepPrefixKind repPrefix = RepPrefixKind.None) =>
			CreateString_Reg_ESRDI(Code.Scasw_AX_m16, addressSize, Register.AX, repPrefix);

		/// <summary>
		/// Creates a <c>REPE SCASW</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		public static Instruction CreateRepeScasw(int addressSize) =>
			CreateString_Reg_ESRDI(Code.Scasw_AX_m16, addressSize, Register.AX, RepPrefixKind.Repe);

		/// <summary>
		/// Creates a <c>REPNE SCASW</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		public static Instruction CreateRepneScasw(int addressSize) =>
			CreateString_Reg_ESRDI(Code.Scasw_AX_m16, addressSize, Register.AX, RepPrefixKind.Repne);

		/// <summary>
		/// Creates a <c>SCASD</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		/// <param name="repPrefix">Rep prefix or <see cref="RepPrefixKind.None"/></param>
		public static Instruction CreateScasd(int addressSize, RepPrefixKind repPrefix = RepPrefixKind.None) =>
			CreateString_Reg_ESRDI(Code.Scasd_EAX_m32, addressSize, Register.EAX, repPrefix);

		/// <summary>
		/// Creates a <c>REPE SCASD</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		public static Instruction CreateRepeScasd(int addressSize) =>
			CreateString_Reg_ESRDI(Code.Scasd_EAX_m32, addressSize, Register.EAX, RepPrefixKind.Repe);

		/// <summary>
		/// Creates a <c>REPNE SCASD</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		public static Instruction CreateRepneScasd(int addressSize) =>
			CreateString_Reg_ESRDI(Code.Scasd_EAX_m32, addressSize, Register.EAX, RepPrefixKind.Repne);

		/// <summary>
		/// Creates a <c>SCASQ</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		/// <param name="repPrefix">Rep prefix or <see cref="RepPrefixKind.None"/></param>
		public static Instruction CreateScasq(int addressSize, RepPrefixKind repPrefix = RepPrefixKind.None) =>
			CreateString_Reg_ESRDI(Code.Scasq_RAX_m64, addressSize, Register.RAX, repPrefix);

		/// <summary>
		/// Creates a <c>REPE SCASQ</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		public static Instruction CreateRepeScasq(int addressSize) =>
			CreateString_Reg_ESRDI(Code.Scasq_RAX_m64, addressSize, Register.RAX, RepPrefixKind.Repe);

		/// <summary>
		/// Creates a <c>REPNE SCASQ</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		public static Instruction CreateRepneScasq(int addressSize) =>
			CreateString_Reg_ESRDI(Code.Scasq_RAX_m64, addressSize, Register.RAX, RepPrefixKind.Repne);

		/// <summary>
		/// Creates a <c>INSB</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		/// <param name="repPrefix">Rep prefix or <see cref="RepPrefixKind.None"/></param>
		public static Instruction CreateInsb(int addressSize, RepPrefixKind repPrefix = RepPrefixKind.None) =>
			CreateString_ESRDI_Reg(Code.Insb_m8_DX, addressSize, Register.DX, repPrefix);

		/// <summary>
		/// Creates a <c>REP INSB</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		public static Instruction CreateRepInsb(int addressSize) =>
			CreateString_ESRDI_Reg(Code.Insb_m8_DX, addressSize, Register.DX, RepPrefixKind.Repe);

		/// <summary>
		/// Creates a <c>INSW</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		/// <param name="repPrefix">Rep prefix or <see cref="RepPrefixKind.None"/></param>
		public static Instruction CreateInsw(int addressSize, RepPrefixKind repPrefix = RepPrefixKind.None) =>
			CreateString_ESRDI_Reg(Code.Insw_m16_DX, addressSize, Register.DX, repPrefix);

		/// <summary>
		/// Creates a <c>REP INSW</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		public static Instruction CreateRepInsw(int addressSize) =>
			CreateString_ESRDI_Reg(Code.Insw_m16_DX, addressSize, Register.DX, RepPrefixKind.Repe);

		/// <summary>
		/// Creates a <c>INSD</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		/// <param name="repPrefix">Rep prefix or <see cref="RepPrefixKind.None"/></param>
		public static Instruction CreateInsd(int addressSize, RepPrefixKind repPrefix = RepPrefixKind.None) =>
			CreateString_ESRDI_Reg(Code.Insd_m32_DX, addressSize, Register.DX, repPrefix);

		/// <summary>
		/// Creates a <c>REP INSD</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		public static Instruction CreateRepInsd(int addressSize) =>
			CreateString_ESRDI_Reg(Code.Insd_m32_DX, addressSize, Register.DX, RepPrefixKind.Repe);

		/// <summary>
		/// Creates a <c>STOSB</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		/// <param name="repPrefix">Rep prefix or <see cref="RepPrefixKind.None"/></param>
		public static Instruction CreateStosb(int addressSize, RepPrefixKind repPrefix = RepPrefixKind.None) =>
			CreateString_ESRDI_Reg(Code.Stosb_m8_AL, addressSize, Register.AL, repPrefix);

		/// <summary>
		/// Creates a <c>REP STOSB</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		public static Instruction CreateRepStosb(int addressSize) =>
			CreateString_ESRDI_Reg(Code.Stosb_m8_AL, addressSize, Register.AL, RepPrefixKind.Repe);

		/// <summary>
		/// Creates a <c>STOSW</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		/// <param name="repPrefix">Rep prefix or <see cref="RepPrefixKind.None"/></param>
		public static Instruction CreateStosw(int addressSize, RepPrefixKind repPrefix = RepPrefixKind.None) =>
			CreateString_ESRDI_Reg(Code.Stosw_m16_AX, addressSize, Register.AX, repPrefix);

		/// <summary>
		/// Creates a <c>REP STOSW</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		public static Instruction CreateRepStosw(int addressSize) =>
			CreateString_ESRDI_Reg(Code.Stosw_m16_AX, addressSize, Register.AX, RepPrefixKind.Repe);

		/// <summary>
		/// Creates a <c>STOSD</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		/// <param name="repPrefix">Rep prefix or <see cref="RepPrefixKind.None"/></param>
		public static Instruction CreateStosd(int addressSize, RepPrefixKind repPrefix = RepPrefixKind.None) =>
			CreateString_ESRDI_Reg(Code.Stosd_m32_EAX, addressSize, Register.EAX, repPrefix);

		/// <summary>
		/// Creates a <c>REP STOSD</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		public static Instruction CreateRepStosd(int addressSize) =>
			CreateString_ESRDI_Reg(Code.Stosd_m32_EAX, addressSize, Register.EAX, RepPrefixKind.Repe);

		/// <summary>
		/// Creates a <c>STOSQ</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		/// <param name="repPrefix">Rep prefix or <see cref="RepPrefixKind.None"/></param>
		public static Instruction CreateStosq(int addressSize, RepPrefixKind repPrefix = RepPrefixKind.None) =>
			CreateString_ESRDI_Reg(Code.Stosq_m64_RAX, addressSize, Register.RAX, repPrefix);

		/// <summary>
		/// Creates a <c>REP STOSQ</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		public static Instruction CreateRepStosq(int addressSize) =>
			CreateString_ESRDI_Reg(Code.Stosq_m64_RAX, addressSize, Register.RAX, RepPrefixKind.Repe);

		/// <summary>
		/// Creates a <c>CMPSB</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		/// <param name="segmentPrefix">Segment override or <see cref="Register.None"/></param>
		/// <param name="repPrefix">Rep prefix or <see cref="RepPrefixKind.None"/></param>
		public static Instruction CreateCmpsb(int addressSize, Register segmentPrefix = Register.None, RepPrefixKind repPrefix = RepPrefixKind.None) =>
			CreateString_SegRSI_ESRDI(Code.Cmpsb_m8_m8, addressSize, segmentPrefix, repPrefix);

		/// <summary>
		/// Creates a <c>REPE CMPSB</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		public static Instruction CreateRepeCmpsb(int addressSize) =>
			CreateString_SegRSI_ESRDI(Code.Cmpsb_m8_m8, addressSize, Register.None, RepPrefixKind.Repe);

		/// <summary>
		/// Creates a <c>REPNE CMPSB</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		public static Instruction CreateRepneCmpsb(int addressSize) =>
			CreateString_SegRSI_ESRDI(Code.Cmpsb_m8_m8, addressSize, Register.None, RepPrefixKind.Repne);

		/// <summary>
		/// Creates a <c>CMPSW</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		/// <param name="segmentPrefix">Segment override or <see cref="Register.None"/></param>
		/// <param name="repPrefix">Rep prefix or <see cref="RepPrefixKind.None"/></param>
		public static Instruction CreateCmpsw(int addressSize, Register segmentPrefix = Register.None, RepPrefixKind repPrefix = RepPrefixKind.None) =>
			CreateString_SegRSI_ESRDI(Code.Cmpsw_m16_m16, addressSize, segmentPrefix, repPrefix);

		/// <summary>
		/// Creates a <c>REPE CMPSW</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		public static Instruction CreateRepeCmpsw(int addressSize) =>
			CreateString_SegRSI_ESRDI(Code.Cmpsw_m16_m16, addressSize, Register.None, RepPrefixKind.Repe);

		/// <summary>
		/// Creates a <c>REPNE CMPSW</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		public static Instruction CreateRepneCmpsw(int addressSize) =>
			CreateString_SegRSI_ESRDI(Code.Cmpsw_m16_m16, addressSize, Register.None, RepPrefixKind.Repne);

		/// <summary>
		/// Creates a <c>CMPSD</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		/// <param name="segmentPrefix">Segment override or <see cref="Register.None"/></param>
		/// <param name="repPrefix">Rep prefix or <see cref="RepPrefixKind.None"/></param>
		public static Instruction CreateCmpsd(int addressSize, Register segmentPrefix = Register.None, RepPrefixKind repPrefix = RepPrefixKind.None) =>
			CreateString_SegRSI_ESRDI(Code.Cmpsd_m32_m32, addressSize, segmentPrefix, repPrefix);

		/// <summary>
		/// Creates a <c>REPE CMPSD</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		public static Instruction CreateRepeCmpsd(int addressSize) =>
			CreateString_SegRSI_ESRDI(Code.Cmpsd_m32_m32, addressSize, Register.None, RepPrefixKind.Repe);

		/// <summary>
		/// Creates a <c>REPNE CMPSD</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		public static Instruction CreateRepneCmpsd(int addressSize) =>
			CreateString_SegRSI_ESRDI(Code.Cmpsd_m32_m32, addressSize, Register.None, RepPrefixKind.Repne);

		/// <summary>
		/// Creates a <c>CMPSQ</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		/// <param name="segmentPrefix">Segment override or <see cref="Register.None"/></param>
		/// <param name="repPrefix">Rep prefix or <see cref="RepPrefixKind.None"/></param>
		public static Instruction CreateCmpsq(int addressSize, Register segmentPrefix = Register.None, RepPrefixKind repPrefix = RepPrefixKind.None) =>
			CreateString_SegRSI_ESRDI(Code.Cmpsq_m64_m64, addressSize, segmentPrefix, repPrefix);

		/// <summary>
		/// Creates a <c>REPE CMPSQ</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		public static Instruction CreateRepeCmpsq(int addressSize) =>
			CreateString_SegRSI_ESRDI(Code.Cmpsq_m64_m64, addressSize, Register.None, RepPrefixKind.Repe);

		/// <summary>
		/// Creates a <c>REPNE CMPSQ</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		public static Instruction CreateRepneCmpsq(int addressSize) =>
			CreateString_SegRSI_ESRDI(Code.Cmpsq_m64_m64, addressSize, Register.None, RepPrefixKind.Repne);

		/// <summary>
		/// Creates a <c>MOVSB</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		/// <param name="segmentPrefix">Segment override or <see cref="Register.None"/></param>
		/// <param name="repPrefix">Rep prefix or <see cref="RepPrefixKind.None"/></param>
		public static Instruction CreateMovsb(int addressSize, Register segmentPrefix = Register.None, RepPrefixKind repPrefix = RepPrefixKind.None) =>
			CreateString_ESRDI_SegRSI(Code.Movsb_m8_m8, addressSize, segmentPrefix, repPrefix);

		/// <summary>
		/// Creates a <c>REP MOVSB</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		public static Instruction CreateRepMovsb(int addressSize) =>
			CreateString_ESRDI_SegRSI(Code.Movsb_m8_m8, addressSize, Register.None, RepPrefixKind.Repe);

		/// <summary>
		/// Creates a <c>MOVSW</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		/// <param name="segmentPrefix">Segment override or <see cref="Register.None"/></param>
		/// <param name="repPrefix">Rep prefix or <see cref="RepPrefixKind.None"/></param>
		public static Instruction CreateMovsw(int addressSize, Register segmentPrefix = Register.None, RepPrefixKind repPrefix = RepPrefixKind.None) =>
			CreateString_ESRDI_SegRSI(Code.Movsw_m16_m16, addressSize, segmentPrefix, repPrefix);

		/// <summary>
		/// Creates a <c>REP MOVSW</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		public static Instruction CreateRepMovsw(int addressSize) =>
			CreateString_ESRDI_SegRSI(Code.Movsw_m16_m16, addressSize, Register.None, RepPrefixKind.Repe);

		/// <summary>
		/// Creates a <c>MOVSD</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		/// <param name="segmentPrefix">Segment override or <see cref="Register.None"/></param>
		/// <param name="repPrefix">Rep prefix or <see cref="RepPrefixKind.None"/></param>
		public static Instruction CreateMovsd(int addressSize, Register segmentPrefix = Register.None, RepPrefixKind repPrefix = RepPrefixKind.None) =>
			CreateString_ESRDI_SegRSI(Code.Movsd_m32_m32, addressSize, segmentPrefix, repPrefix);

		/// <summary>
		/// Creates a <c>REP MOVSD</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		public static Instruction CreateRepMovsd(int addressSize) =>
			CreateString_ESRDI_SegRSI(Code.Movsd_m32_m32, addressSize, Register.None, RepPrefixKind.Repe);

		/// <summary>
		/// Creates a <c>MOVSQ</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		/// <param name="segmentPrefix">Segment override or <see cref="Register.None"/></param>
		/// <param name="repPrefix">Rep prefix or <see cref="RepPrefixKind.None"/></param>
		public static Instruction CreateMovsq(int addressSize, Register segmentPrefix = Register.None, RepPrefixKind repPrefix = RepPrefixKind.None) =>
			CreateString_ESRDI_SegRSI(Code.Movsq_m64_m64, addressSize, segmentPrefix, repPrefix);

		/// <summary>
		/// Creates a <c>REP MOVSQ</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		public static Instruction CreateRepMovsq(int addressSize) =>
			CreateString_ESRDI_SegRSI(Code.Movsq_m64_m64, addressSize, Register.None, RepPrefixKind.Repe);

		/// <summary>
		/// Creates a <c>MASKMOVQ</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		/// <param name="register1">Register</param>
		/// <param name="register2">Register</param>
		/// <param name="segmentPrefix">Segment override or <see cref="Register.None"/></param>
		public static Instruction CreateMaskmovq(int addressSize, Register register1, Register register2, Register segmentPrefix = Register.None) =>
			CreateMaskmov(Code.Maskmovq_rDI_mm_mm, addressSize, register1, register2, segmentPrefix);

		/// <summary>
		/// Creates a <c>MASKMOVDQU</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		/// <param name="register1">Register</param>
		/// <param name="register2">Register</param>
		/// <param name="segmentPrefix">Segment override or <see cref="Register.None"/></param>
		public static Instruction CreateMaskmovdqu(int addressSize, Register register1, Register register2, Register segmentPrefix = Register.None) =>
			CreateMaskmov(Code.Maskmovdqu_rDI_xmm_xmm, addressSize, register1, register2, segmentPrefix);

		/// <summary>
		/// Creates a <c>VMASKMOVDQU</c> instruction
		/// </summary>
		/// <param name="addressSize">16, 32, or 64</param>
		/// <param name="register1">Register</param>
		/// <param name="register2">Register</param>
		/// <param name="segmentPrefix">Segment override or <see cref="Register.None"/></param>
		public static Instruction CreateVmaskmovdqu(int addressSize, Register register1, Register register2, Register segmentPrefix = Register.None) =>
			CreateMaskmov(Code.VEX_Vmaskmovdqu_rDI_xmm_xmm, addressSize, register1, register2, segmentPrefix);

		/// <summary>
		/// Creates a <c>db</c>/<c>.byte</c> asm directive
		/// </summary>
		/// <param name="b0">Byte 0</param>
		public static Instruction CreateDeclareByte(byte b0) {
			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareByte;
			instruction.InternalDeclareDataCount = 1;

			instruction.SetDeclareByteValue(0, b0);

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}

		/// <summary>
		/// Creates a <c>db</c>/<c>.byte</c> asm directive
		/// </summary>
		/// <param name="b0">Byte 0</param>
		/// <param name="b1">Byte 1</param>
		public static Instruction CreateDeclareByte(byte b0, byte b1) {
			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareByte;
			instruction.InternalDeclareDataCount = 2;

			instruction.SetDeclareByteValue(0, b0);
			instruction.SetDeclareByteValue(1, b1);

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}

		/// <summary>
		/// Creates a <c>db</c>/<c>.byte</c> asm directive
		/// </summary>
		/// <param name="b0">Byte 0</param>
		/// <param name="b1">Byte 1</param>
		/// <param name="b2">Byte 2</param>
		public static Instruction CreateDeclareByte(byte b0, byte b1, byte b2) {
			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareByte;
			instruction.InternalDeclareDataCount = 3;

			instruction.SetDeclareByteValue(0, b0);
			instruction.SetDeclareByteValue(1, b1);
			instruction.SetDeclareByteValue(2, b2);

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}

		/// <summary>
		/// Creates a <c>db</c>/<c>.byte</c> asm directive
		/// </summary>
		/// <param name="b0">Byte 0</param>
		/// <param name="b1">Byte 1</param>
		/// <param name="b2">Byte 2</param>
		/// <param name="b3">Byte 3</param>
		public static Instruction CreateDeclareByte(byte b0, byte b1, byte b2, byte b3) {
			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareByte;
			instruction.InternalDeclareDataCount = 4;

			instruction.SetDeclareByteValue(0, b0);
			instruction.SetDeclareByteValue(1, b1);
			instruction.SetDeclareByteValue(2, b2);
			instruction.SetDeclareByteValue(3, b3);

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}

		/// <summary>
		/// Creates a <c>db</c>/<c>.byte</c> asm directive
		/// </summary>
		/// <param name="b0">Byte 0</param>
		/// <param name="b1">Byte 1</param>
		/// <param name="b2">Byte 2</param>
		/// <param name="b3">Byte 3</param>
		/// <param name="b4">Byte 4</param>
		public static Instruction CreateDeclareByte(byte b0, byte b1, byte b2, byte b3, byte b4) {
			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareByte;
			instruction.InternalDeclareDataCount = 5;

			instruction.SetDeclareByteValue(0, b0);
			instruction.SetDeclareByteValue(1, b1);
			instruction.SetDeclareByteValue(2, b2);
			instruction.SetDeclareByteValue(3, b3);
			instruction.SetDeclareByteValue(4, b4);

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}

		/// <summary>
		/// Creates a <c>db</c>/<c>.byte</c> asm directive
		/// </summary>
		/// <param name="b0">Byte 0</param>
		/// <param name="b1">Byte 1</param>
		/// <param name="b2">Byte 2</param>
		/// <param name="b3">Byte 3</param>
		/// <param name="b4">Byte 4</param>
		/// <param name="b5">Byte 5</param>
		public static Instruction CreateDeclareByte(byte b0, byte b1, byte b2, byte b3, byte b4, byte b5) {
			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareByte;
			instruction.InternalDeclareDataCount = 6;

			instruction.SetDeclareByteValue(0, b0);
			instruction.SetDeclareByteValue(1, b1);
			instruction.SetDeclareByteValue(2, b2);
			instruction.SetDeclareByteValue(3, b3);
			instruction.SetDeclareByteValue(4, b4);
			instruction.SetDeclareByteValue(5, b5);

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}

		/// <summary>
		/// Creates a <c>db</c>/<c>.byte</c> asm directive
		/// </summary>
		/// <param name="b0">Byte 0</param>
		/// <param name="b1">Byte 1</param>
		/// <param name="b2">Byte 2</param>
		/// <param name="b3">Byte 3</param>
		/// <param name="b4">Byte 4</param>
		/// <param name="b5">Byte 5</param>
		/// <param name="b6">Byte 6</param>
		public static Instruction CreateDeclareByte(byte b0, byte b1, byte b2, byte b3, byte b4, byte b5, byte b6) {
			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareByte;
			instruction.InternalDeclareDataCount = 7;

			instruction.SetDeclareByteValue(0, b0);
			instruction.SetDeclareByteValue(1, b1);
			instruction.SetDeclareByteValue(2, b2);
			instruction.SetDeclareByteValue(3, b3);
			instruction.SetDeclareByteValue(4, b4);
			instruction.SetDeclareByteValue(5, b5);
			instruction.SetDeclareByteValue(6, b6);

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}

		/// <summary>
		/// Creates a <c>db</c>/<c>.byte</c> asm directive
		/// </summary>
		/// <param name="b0">Byte 0</param>
		/// <param name="b1">Byte 1</param>
		/// <param name="b2">Byte 2</param>
		/// <param name="b3">Byte 3</param>
		/// <param name="b4">Byte 4</param>
		/// <param name="b5">Byte 5</param>
		/// <param name="b6">Byte 6</param>
		/// <param name="b7">Byte 7</param>
		public static Instruction CreateDeclareByte(byte b0, byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7) {
			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareByte;
			instruction.InternalDeclareDataCount = 8;

			instruction.SetDeclareByteValue(0, b0);
			instruction.SetDeclareByteValue(1, b1);
			instruction.SetDeclareByteValue(2, b2);
			instruction.SetDeclareByteValue(3, b3);
			instruction.SetDeclareByteValue(4, b4);
			instruction.SetDeclareByteValue(5, b5);
			instruction.SetDeclareByteValue(6, b6);
			instruction.SetDeclareByteValue(7, b7);

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}

		/// <summary>
		/// Creates a <c>db</c>/<c>.byte</c> asm directive
		/// </summary>
		/// <param name="b0">Byte 0</param>
		/// <param name="b1">Byte 1</param>
		/// <param name="b2">Byte 2</param>
		/// <param name="b3">Byte 3</param>
		/// <param name="b4">Byte 4</param>
		/// <param name="b5">Byte 5</param>
		/// <param name="b6">Byte 6</param>
		/// <param name="b7">Byte 7</param>
		/// <param name="b8">Byte 8</param>
		public static Instruction CreateDeclareByte(byte b0, byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7, byte b8) {
			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareByte;
			instruction.InternalDeclareDataCount = 9;

			instruction.SetDeclareByteValue(0, b0);
			instruction.SetDeclareByteValue(1, b1);
			instruction.SetDeclareByteValue(2, b2);
			instruction.SetDeclareByteValue(3, b3);
			instruction.SetDeclareByteValue(4, b4);
			instruction.SetDeclareByteValue(5, b5);
			instruction.SetDeclareByteValue(6, b6);
			instruction.SetDeclareByteValue(7, b7);
			instruction.SetDeclareByteValue(8, b8);

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}

		/// <summary>
		/// Creates a <c>db</c>/<c>.byte</c> asm directive
		/// </summary>
		/// <param name="b0">Byte 0</param>
		/// <param name="b1">Byte 1</param>
		/// <param name="b2">Byte 2</param>
		/// <param name="b3">Byte 3</param>
		/// <param name="b4">Byte 4</param>
		/// <param name="b5">Byte 5</param>
		/// <param name="b6">Byte 6</param>
		/// <param name="b7">Byte 7</param>
		/// <param name="b8">Byte 8</param>
		/// <param name="b9">Byte 9</param>
		public static Instruction CreateDeclareByte(byte b0, byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7, byte b8, byte b9) {
			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareByte;
			instruction.InternalDeclareDataCount = 10;

			instruction.SetDeclareByteValue(0, b0);
			instruction.SetDeclareByteValue(1, b1);
			instruction.SetDeclareByteValue(2, b2);
			instruction.SetDeclareByteValue(3, b3);
			instruction.SetDeclareByteValue(4, b4);
			instruction.SetDeclareByteValue(5, b5);
			instruction.SetDeclareByteValue(6, b6);
			instruction.SetDeclareByteValue(7, b7);
			instruction.SetDeclareByteValue(8, b8);
			instruction.SetDeclareByteValue(9, b9);

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}

		/// <summary>
		/// Creates a <c>db</c>/<c>.byte</c> asm directive
		/// </summary>
		/// <param name="b0">Byte 0</param>
		/// <param name="b1">Byte 1</param>
		/// <param name="b2">Byte 2</param>
		/// <param name="b3">Byte 3</param>
		/// <param name="b4">Byte 4</param>
		/// <param name="b5">Byte 5</param>
		/// <param name="b6">Byte 6</param>
		/// <param name="b7">Byte 7</param>
		/// <param name="b8">Byte 8</param>
		/// <param name="b9">Byte 9</param>
		/// <param name="b10">Byte 10</param>
		public static Instruction CreateDeclareByte(byte b0, byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7, byte b8, byte b9, byte b10) {
			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareByte;
			instruction.InternalDeclareDataCount = 11;

			instruction.SetDeclareByteValue(0, b0);
			instruction.SetDeclareByteValue(1, b1);
			instruction.SetDeclareByteValue(2, b2);
			instruction.SetDeclareByteValue(3, b3);
			instruction.SetDeclareByteValue(4, b4);
			instruction.SetDeclareByteValue(5, b5);
			instruction.SetDeclareByteValue(6, b6);
			instruction.SetDeclareByteValue(7, b7);
			instruction.SetDeclareByteValue(8, b8);
			instruction.SetDeclareByteValue(9, b9);
			instruction.SetDeclareByteValue(10, b10);

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}

		/// <summary>
		/// Creates a <c>db</c>/<c>.byte</c> asm directive
		/// </summary>
		/// <param name="b0">Byte 0</param>
		/// <param name="b1">Byte 1</param>
		/// <param name="b2">Byte 2</param>
		/// <param name="b3">Byte 3</param>
		/// <param name="b4">Byte 4</param>
		/// <param name="b5">Byte 5</param>
		/// <param name="b6">Byte 6</param>
		/// <param name="b7">Byte 7</param>
		/// <param name="b8">Byte 8</param>
		/// <param name="b9">Byte 9</param>
		/// <param name="b10">Byte 10</param>
		/// <param name="b11">Byte 11</param>
		public static Instruction CreateDeclareByte(byte b0, byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7, byte b8, byte b9, byte b10, byte b11) {
			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareByte;
			instruction.InternalDeclareDataCount = 12;

			instruction.SetDeclareByteValue(0, b0);
			instruction.SetDeclareByteValue(1, b1);
			instruction.SetDeclareByteValue(2, b2);
			instruction.SetDeclareByteValue(3, b3);
			instruction.SetDeclareByteValue(4, b4);
			instruction.SetDeclareByteValue(5, b5);
			instruction.SetDeclareByteValue(6, b6);
			instruction.SetDeclareByteValue(7, b7);
			instruction.SetDeclareByteValue(8, b8);
			instruction.SetDeclareByteValue(9, b9);
			instruction.SetDeclareByteValue(10, b10);
			instruction.SetDeclareByteValue(11, b11);

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}

		/// <summary>
		/// Creates a <c>db</c>/<c>.byte</c> asm directive
		/// </summary>
		/// <param name="b0">Byte 0</param>
		/// <param name="b1">Byte 1</param>
		/// <param name="b2">Byte 2</param>
		/// <param name="b3">Byte 3</param>
		/// <param name="b4">Byte 4</param>
		/// <param name="b5">Byte 5</param>
		/// <param name="b6">Byte 6</param>
		/// <param name="b7">Byte 7</param>
		/// <param name="b8">Byte 8</param>
		/// <param name="b9">Byte 9</param>
		/// <param name="b10">Byte 10</param>
		/// <param name="b11">Byte 11</param>
		/// <param name="b12">Byte 12</param>
		public static Instruction CreateDeclareByte(byte b0, byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7, byte b8, byte b9, byte b10, byte b11, byte b12) {
			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareByte;
			instruction.InternalDeclareDataCount = 13;

			instruction.SetDeclareByteValue(0, b0);
			instruction.SetDeclareByteValue(1, b1);
			instruction.SetDeclareByteValue(2, b2);
			instruction.SetDeclareByteValue(3, b3);
			instruction.SetDeclareByteValue(4, b4);
			instruction.SetDeclareByteValue(5, b5);
			instruction.SetDeclareByteValue(6, b6);
			instruction.SetDeclareByteValue(7, b7);
			instruction.SetDeclareByteValue(8, b8);
			instruction.SetDeclareByteValue(9, b9);
			instruction.SetDeclareByteValue(10, b10);
			instruction.SetDeclareByteValue(11, b11);
			instruction.SetDeclareByteValue(12, b12);

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}

		/// <summary>
		/// Creates a <c>db</c>/<c>.byte</c> asm directive
		/// </summary>
		/// <param name="b0">Byte 0</param>
		/// <param name="b1">Byte 1</param>
		/// <param name="b2">Byte 2</param>
		/// <param name="b3">Byte 3</param>
		/// <param name="b4">Byte 4</param>
		/// <param name="b5">Byte 5</param>
		/// <param name="b6">Byte 6</param>
		/// <param name="b7">Byte 7</param>
		/// <param name="b8">Byte 8</param>
		/// <param name="b9">Byte 9</param>
		/// <param name="b10">Byte 10</param>
		/// <param name="b11">Byte 11</param>
		/// <param name="b12">Byte 12</param>
		/// <param name="b13">Byte 13</param>
		public static Instruction CreateDeclareByte(byte b0, byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7, byte b8, byte b9, byte b10, byte b11, byte b12, byte b13) {
			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareByte;
			instruction.InternalDeclareDataCount = 14;

			instruction.SetDeclareByteValue(0, b0);
			instruction.SetDeclareByteValue(1, b1);
			instruction.SetDeclareByteValue(2, b2);
			instruction.SetDeclareByteValue(3, b3);
			instruction.SetDeclareByteValue(4, b4);
			instruction.SetDeclareByteValue(5, b5);
			instruction.SetDeclareByteValue(6, b6);
			instruction.SetDeclareByteValue(7, b7);
			instruction.SetDeclareByteValue(8, b8);
			instruction.SetDeclareByteValue(9, b9);
			instruction.SetDeclareByteValue(10, b10);
			instruction.SetDeclareByteValue(11, b11);
			instruction.SetDeclareByteValue(12, b12);
			instruction.SetDeclareByteValue(13, b13);

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}

		/// <summary>
		/// Creates a <c>db</c>/<c>.byte</c> asm directive
		/// </summary>
		/// <param name="b0">Byte 0</param>
		/// <param name="b1">Byte 1</param>
		/// <param name="b2">Byte 2</param>
		/// <param name="b3">Byte 3</param>
		/// <param name="b4">Byte 4</param>
		/// <param name="b5">Byte 5</param>
		/// <param name="b6">Byte 6</param>
		/// <param name="b7">Byte 7</param>
		/// <param name="b8">Byte 8</param>
		/// <param name="b9">Byte 9</param>
		/// <param name="b10">Byte 10</param>
		/// <param name="b11">Byte 11</param>
		/// <param name="b12">Byte 12</param>
		/// <param name="b13">Byte 13</param>
		/// <param name="b14">Byte 14</param>
		public static Instruction CreateDeclareByte(byte b0, byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7, byte b8, byte b9, byte b10, byte b11, byte b12, byte b13, byte b14) {
			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareByte;
			instruction.InternalDeclareDataCount = 15;

			instruction.SetDeclareByteValue(0, b0);
			instruction.SetDeclareByteValue(1, b1);
			instruction.SetDeclareByteValue(2, b2);
			instruction.SetDeclareByteValue(3, b3);
			instruction.SetDeclareByteValue(4, b4);
			instruction.SetDeclareByteValue(5, b5);
			instruction.SetDeclareByteValue(6, b6);
			instruction.SetDeclareByteValue(7, b7);
			instruction.SetDeclareByteValue(8, b8);
			instruction.SetDeclareByteValue(9, b9);
			instruction.SetDeclareByteValue(10, b10);
			instruction.SetDeclareByteValue(11, b11);
			instruction.SetDeclareByteValue(12, b12);
			instruction.SetDeclareByteValue(13, b13);
			instruction.SetDeclareByteValue(14, b14);

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}

		/// <summary>
		/// Creates a <c>db</c>/<c>.byte</c> asm directive
		/// </summary>
		/// <param name="b0">Byte 0</param>
		/// <param name="b1">Byte 1</param>
		/// <param name="b2">Byte 2</param>
		/// <param name="b3">Byte 3</param>
		/// <param name="b4">Byte 4</param>
		/// <param name="b5">Byte 5</param>
		/// <param name="b6">Byte 6</param>
		/// <param name="b7">Byte 7</param>
		/// <param name="b8">Byte 8</param>
		/// <param name="b9">Byte 9</param>
		/// <param name="b10">Byte 10</param>
		/// <param name="b11">Byte 11</param>
		/// <param name="b12">Byte 12</param>
		/// <param name="b13">Byte 13</param>
		/// <param name="b14">Byte 14</param>
		/// <param name="b15">Byte 15</param>
		public static Instruction CreateDeclareByte(byte b0, byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7, byte b8, byte b9, byte b10, byte b11, byte b12, byte b13, byte b14, byte b15) {
			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareByte;
			instruction.InternalDeclareDataCount = 16;

			instruction.SetDeclareByteValue(0, b0);
			instruction.SetDeclareByteValue(1, b1);
			instruction.SetDeclareByteValue(2, b2);
			instruction.SetDeclareByteValue(3, b3);
			instruction.SetDeclareByteValue(4, b4);
			instruction.SetDeclareByteValue(5, b5);
			instruction.SetDeclareByteValue(6, b6);
			instruction.SetDeclareByteValue(7, b7);
			instruction.SetDeclareByteValue(8, b8);
			instruction.SetDeclareByteValue(9, b9);
			instruction.SetDeclareByteValue(10, b10);
			instruction.SetDeclareByteValue(11, b11);
			instruction.SetDeclareByteValue(12, b12);
			instruction.SetDeclareByteValue(13, b13);
			instruction.SetDeclareByteValue(14, b14);
			instruction.SetDeclareByteValue(15, b15);

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}

#if HAS_SPAN
		/// <summary>
		/// Creates a <c>db</c>/<c>.byte</c> asm directive
		/// </summary>
		/// <param name="data">Data</param>
		public static Instruction CreateDeclareByte(ReadOnlySpan<byte> data) {
			if ((uint)data.Length - 1 > 16 - 1)
				ThrowHelper.ThrowArgumentOutOfRangeException_data();

			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareByte;
			instruction.InternalDeclareDataCount = (uint)data.Length;

			for (int i = 0; i < data.Length; i++)
				instruction.SetDeclareByteValue(i, data[i]);

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}
#endif

		/// <summary>
		/// Creates a <c>db</c>/<c>.byte</c> asm directive
		/// </summary>
		/// <param name="data">Data</param>
		public static Instruction CreateDeclareByte(byte[] data) {
			if (data is null)
				ThrowHelper.ThrowArgumentNullException_data();
			return CreateDeclareByte(data, 0, data.Length);
		}

		/// <summary>
		/// Creates a <c>db</c>/<c>.byte</c> asm directive
		/// </summary>
		/// <param name="data">Data</param>
		/// <param name="index">Start index</param>
		/// <param name="length">Number of bytes</param>
		public static Instruction CreateDeclareByte(byte[] data, int index, int length) {
			if (data is null)
				ThrowHelper.ThrowArgumentNullException_data();
			if ((uint)length - 1 > 16 - 1)
				ThrowHelper.ThrowArgumentOutOfRangeException_length();
			if ((ulong)(uint)index + (uint)length > (uint)data.Length)
				ThrowHelper.ThrowArgumentOutOfRangeException_index();

			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareByte;
			instruction.InternalDeclareDataCount = (uint)length;

			for (int i = 0; i < length; i++)
				instruction.SetDeclareByteValue(i, data[index + i]);

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}

		/// <summary>
		/// Creates a <c>dw</c>/<c>.word</c> asm directive
		/// </summary>
		/// <param name="w0">Word 0</param>
		public static Instruction CreateDeclareWord(ushort w0) {
			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareWord;
			instruction.InternalDeclareDataCount = 1;

			instruction.SetDeclareWordValue(0, w0);

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}

		/// <summary>
		/// Creates a <c>dw</c>/<c>.word</c> asm directive
		/// </summary>
		/// <param name="w0">Word 0</param>
		/// <param name="w1">Word 1</param>
		public static Instruction CreateDeclareWord(ushort w0, ushort w1) {
			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareWord;
			instruction.InternalDeclareDataCount = 2;

			instruction.SetDeclareWordValue(0, w0);
			instruction.SetDeclareWordValue(1, w1);

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}

		/// <summary>
		/// Creates a <c>dw</c>/<c>.word</c> asm directive
		/// </summary>
		/// <param name="w0">Word 0</param>
		/// <param name="w1">Word 1</param>
		/// <param name="w2">Word 2</param>
		public static Instruction CreateDeclareWord(ushort w0, ushort w1, ushort w2) {
			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareWord;
			instruction.InternalDeclareDataCount = 3;

			instruction.SetDeclareWordValue(0, w0);
			instruction.SetDeclareWordValue(1, w1);
			instruction.SetDeclareWordValue(2, w2);

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}

		/// <summary>
		/// Creates a <c>dw</c>/<c>.word</c> asm directive
		/// </summary>
		/// <param name="w0">Word 0</param>
		/// <param name="w1">Word 1</param>
		/// <param name="w2">Word 2</param>
		/// <param name="w3">Word 3</param>
		public static Instruction CreateDeclareWord(ushort w0, ushort w1, ushort w2, ushort w3) {
			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareWord;
			instruction.InternalDeclareDataCount = 4;

			instruction.SetDeclareWordValue(0, w0);
			instruction.SetDeclareWordValue(1, w1);
			instruction.SetDeclareWordValue(2, w2);
			instruction.SetDeclareWordValue(3, w3);

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}

		/// <summary>
		/// Creates a <c>dw</c>/<c>.word</c> asm directive
		/// </summary>
		/// <param name="w0">Word 0</param>
		/// <param name="w1">Word 1</param>
		/// <param name="w2">Word 2</param>
		/// <param name="w3">Word 3</param>
		/// <param name="w4">Word 4</param>
		public static Instruction CreateDeclareWord(ushort w0, ushort w1, ushort w2, ushort w3, ushort w4) {
			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareWord;
			instruction.InternalDeclareDataCount = 5;

			instruction.SetDeclareWordValue(0, w0);
			instruction.SetDeclareWordValue(1, w1);
			instruction.SetDeclareWordValue(2, w2);
			instruction.SetDeclareWordValue(3, w3);
			instruction.SetDeclareWordValue(4, w4);

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}

		/// <summary>
		/// Creates a <c>dw</c>/<c>.word</c> asm directive
		/// </summary>
		/// <param name="w0">Word 0</param>
		/// <param name="w1">Word 1</param>
		/// <param name="w2">Word 2</param>
		/// <param name="w3">Word 3</param>
		/// <param name="w4">Word 4</param>
		/// <param name="w5">Word 5</param>
		public static Instruction CreateDeclareWord(ushort w0, ushort w1, ushort w2, ushort w3, ushort w4, ushort w5) {
			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareWord;
			instruction.InternalDeclareDataCount = 6;

			instruction.SetDeclareWordValue(0, w0);
			instruction.SetDeclareWordValue(1, w1);
			instruction.SetDeclareWordValue(2, w2);
			instruction.SetDeclareWordValue(3, w3);
			instruction.SetDeclareWordValue(4, w4);
			instruction.SetDeclareWordValue(5, w5);

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}

		/// <summary>
		/// Creates a <c>dw</c>/<c>.word</c> asm directive
		/// </summary>
		/// <param name="w0">Word 0</param>
		/// <param name="w1">Word 1</param>
		/// <param name="w2">Word 2</param>
		/// <param name="w3">Word 3</param>
		/// <param name="w4">Word 4</param>
		/// <param name="w5">Word 5</param>
		/// <param name="w6">Word 6</param>
		public static Instruction CreateDeclareWord(ushort w0, ushort w1, ushort w2, ushort w3, ushort w4, ushort w5, ushort w6) {
			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareWord;
			instruction.InternalDeclareDataCount = 7;

			instruction.SetDeclareWordValue(0, w0);
			instruction.SetDeclareWordValue(1, w1);
			instruction.SetDeclareWordValue(2, w2);
			instruction.SetDeclareWordValue(3, w3);
			instruction.SetDeclareWordValue(4, w4);
			instruction.SetDeclareWordValue(5, w5);
			instruction.SetDeclareWordValue(6, w6);

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}

		/// <summary>
		/// Creates a <c>dw</c>/<c>.word</c> asm directive
		/// </summary>
		/// <param name="w0">Word 0</param>
		/// <param name="w1">Word 1</param>
		/// <param name="w2">Word 2</param>
		/// <param name="w3">Word 3</param>
		/// <param name="w4">Word 4</param>
		/// <param name="w5">Word 5</param>
		/// <param name="w6">Word 6</param>
		/// <param name="w7">Word 7</param>
		public static Instruction CreateDeclareWord(ushort w0, ushort w1, ushort w2, ushort w3, ushort w4, ushort w5, ushort w6, ushort w7) {
			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareWord;
			instruction.InternalDeclareDataCount = 8;

			instruction.SetDeclareWordValue(0, w0);
			instruction.SetDeclareWordValue(1, w1);
			instruction.SetDeclareWordValue(2, w2);
			instruction.SetDeclareWordValue(3, w3);
			instruction.SetDeclareWordValue(4, w4);
			instruction.SetDeclareWordValue(5, w5);
			instruction.SetDeclareWordValue(6, w6);
			instruction.SetDeclareWordValue(7, w7);

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}

#if HAS_SPAN
		/// <summary>
		/// Creates a <c>dw</c>/<c>.word</c> asm directive
		/// </summary>
		/// <param name="data">Data</param>
		public static Instruction CreateDeclareWord(ReadOnlySpan<byte> data) {
			if ((uint)data.Length - 1 > 16 - 1 || ((uint)data.Length & 1) != 0)
				ThrowHelper.ThrowArgumentOutOfRangeException_data();

			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareWord;
			instruction.InternalDeclareDataCount = (uint)data.Length / 2;

			for (int i = 0; i < data.Length; i += 2) {
				uint v = data[i] | ((uint)data[i + 1] << 8);
				instruction.SetDeclareWordValue(i / 2, (ushort)v);
			}

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}
#endif

		/// <summary>
		/// Creates a <c>dw</c>/<c>.word</c> asm directive
		/// </summary>
		/// <param name="data">Data</param>
		public static Instruction CreateDeclareWord(byte[] data) {
			if (data is null)
				ThrowHelper.ThrowArgumentNullException_data();
			return CreateDeclareWord(data, 0, data.Length);
		}

		/// <summary>
		/// Creates a <c>dw</c>/<c>.word</c> asm directive
		/// </summary>
		/// <param name="data">Data</param>
		/// <param name="index">Start index</param>
		/// <param name="length">Number of bytes</param>
		public static Instruction CreateDeclareWord(byte[] data, int index, int length) {
			if (data is null)
				ThrowHelper.ThrowArgumentNullException_data();
			if ((uint)length - 1 > 16 - 1 || ((uint)length & 1) != 0)
				ThrowHelper.ThrowArgumentOutOfRangeException_length();
			if ((ulong)(uint)index + (uint)length > (uint)data.Length)
				ThrowHelper.ThrowArgumentOutOfRangeException_index();

			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareWord;
			instruction.InternalDeclareDataCount = (uint)length / 2;

			for (int i = 0; i < length; i += 2) {
				uint v = data[index + i] | ((uint)data[index + i + 1] << 8);
				instruction.SetDeclareWordValue(i / 2, (ushort)v);
			}

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}

#if HAS_SPAN
		/// <summary>
		/// Creates a <c>dw</c>/<c>.word</c> asm directive
		/// </summary>
		/// <param name="data">Data</param>
		public static Instruction CreateDeclareWord(ReadOnlySpan<ushort> data) {
			if ((uint)data.Length - 1 > 8 - 1)
				ThrowHelper.ThrowArgumentOutOfRangeException_data();

			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareWord;
			instruction.InternalDeclareDataCount = (uint)data.Length;

			for (int i = 0; i < data.Length; i++)
				instruction.SetDeclareWordValue(i, data[i]);

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}
#endif

		/// <summary>
		/// Creates a <c>dw</c>/<c>.word</c> asm directive
		/// </summary>
		/// <param name="data">Data</param>
		public static Instruction CreateDeclareWord(ushort[] data) {
			if (data is null)
				ThrowHelper.ThrowArgumentNullException_data();
			return CreateDeclareWord(data, 0, data.Length);
		}

		/// <summary>
		/// Creates a <c>dw</c>/<c>.word</c> asm directive
		/// </summary>
		/// <param name="data">Data</param>
		/// <param name="index">Start index</param>
		/// <param name="length">Number of elements</param>
		public static Instruction CreateDeclareWord(ushort[] data, int index, int length) {
			if (data is null)
				ThrowHelper.ThrowArgumentNullException_data();
			if ((uint)length - 1 > 8 - 1)
				ThrowHelper.ThrowArgumentOutOfRangeException_length();
			if ((ulong)(uint)index + (uint)length > (uint)data.Length)
				ThrowHelper.ThrowArgumentOutOfRangeException_index();

			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareWord;
			instruction.InternalDeclareDataCount = (uint)length;

			for (int i = 0; i < length; i++)
				instruction.SetDeclareWordValue(i, data[index + i]);

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}

		/// <summary>
		/// Creates a <c>dd</c>/<c>.int</c> asm directive
		/// </summary>
		/// <param name="d0">Dword 0</param>
		public static Instruction CreateDeclareDword(uint d0) {
			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareDword;
			instruction.InternalDeclareDataCount = 1;

			instruction.SetDeclareDwordValue(0, d0);

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}

		/// <summary>
		/// Creates a <c>dd</c>/<c>.int</c> asm directive
		/// </summary>
		/// <param name="d0">Dword 0</param>
		/// <param name="d1">Dword 1</param>
		public static Instruction CreateDeclareDword(uint d0, uint d1) {
			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareDword;
			instruction.InternalDeclareDataCount = 2;

			instruction.SetDeclareDwordValue(0, d0);
			instruction.SetDeclareDwordValue(1, d1);

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}

		/// <summary>
		/// Creates a <c>dd</c>/<c>.int</c> asm directive
		/// </summary>
		/// <param name="d0">Dword 0</param>
		/// <param name="d1">Dword 1</param>
		/// <param name="d2">Dword 2</param>
		public static Instruction CreateDeclareDword(uint d0, uint d1, uint d2) {
			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareDword;
			instruction.InternalDeclareDataCount = 3;

			instruction.SetDeclareDwordValue(0, d0);
			instruction.SetDeclareDwordValue(1, d1);
			instruction.SetDeclareDwordValue(2, d2);

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}

		/// <summary>
		/// Creates a <c>dd</c>/<c>.int</c> asm directive
		/// </summary>
		/// <param name="d0">Dword 0</param>
		/// <param name="d1">Dword 1</param>
		/// <param name="d2">Dword 2</param>
		/// <param name="d3">Dword 3</param>
		public static Instruction CreateDeclareDword(uint d0, uint d1, uint d2, uint d3) {
			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareDword;
			instruction.InternalDeclareDataCount = 4;

			instruction.SetDeclareDwordValue(0, d0);
			instruction.SetDeclareDwordValue(1, d1);
			instruction.SetDeclareDwordValue(2, d2);
			instruction.SetDeclareDwordValue(3, d3);

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}

#if HAS_SPAN
		/// <summary>
		/// Creates a <c>dd</c>/<c>.int</c> asm directive
		/// </summary>
		/// <param name="data">Data</param>
		public static Instruction CreateDeclareDword(ReadOnlySpan<byte> data) {
			if ((uint)data.Length - 1 > 16 - 1 || ((uint)data.Length & 3) != 0)
				ThrowHelper.ThrowArgumentOutOfRangeException_data();

			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareDword;
			instruction.InternalDeclareDataCount = (uint)data.Length / 4;

			for (int i = 0; i < data.Length; i += 4) {
				uint v = data[i] | ((uint)data[i + 1] << 8) | ((uint)data[i + 2] << 16) | ((uint)data[i + 3] << 24);
				instruction.SetDeclareDwordValue(i / 4, v);
			}

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}
#endif

		/// <summary>
		/// Creates a <c>dd</c>/<c>.int</c> asm directive
		/// </summary>
		/// <param name="data">Data</param>
		public static Instruction CreateDeclareDword(byte[] data) {
			if (data is null)
				ThrowHelper.ThrowArgumentNullException_data();
			return CreateDeclareDword(data, 0, data.Length);
		}

		/// <summary>
		/// Creates a <c>dd</c>/<c>.int</c> asm directive
		/// </summary>
		/// <param name="data">Data</param>
		/// <param name="index">Start index</param>
		/// <param name="length">Number of bytes</param>
		public static Instruction CreateDeclareDword(byte[] data, int index, int length) {
			if (data is null)
				ThrowHelper.ThrowArgumentNullException_data();
			if ((uint)length - 1 > 16 - 1 || ((uint)length & 3) != 0)
				ThrowHelper.ThrowArgumentOutOfRangeException_length();
			if ((ulong)(uint)index + (uint)length > (uint)data.Length)
				ThrowHelper.ThrowArgumentOutOfRangeException_index();

			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareDword;
			instruction.InternalDeclareDataCount = (uint)length / 4;

			for (int i = 0; i < length; i += 4) {
				uint v = data[index + i] | ((uint)data[index + i + 1] << 8) | ((uint)data[index + i + 2] << 16) | ((uint)data[index + i + 3] << 24);
				instruction.SetDeclareDwordValue(i / 4, v);
			}

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}

#if HAS_SPAN
		/// <summary>
		/// Creates a <c>dd</c>/<c>.int</c> asm directive
		/// </summary>
		/// <param name="data">Data</param>
		public static Instruction CreateDeclareDword(ReadOnlySpan<uint> data) {
			if ((uint)data.Length - 1 > 4 - 1)
				ThrowHelper.ThrowArgumentOutOfRangeException_data();

			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareDword;
			instruction.InternalDeclareDataCount = (uint)data.Length;

			for (int i = 0; i < data.Length; i++)
				instruction.SetDeclareDwordValue(i, data[i]);

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}
#endif

		/// <summary>
		/// Creates a <c>dd</c>/<c>.int</c> asm directive
		/// </summary>
		/// <param name="data">Data</param>
		public static Instruction CreateDeclareDword(uint[] data) {
			if (data is null)
				ThrowHelper.ThrowArgumentNullException_data();
			return CreateDeclareDword(data, 0, data.Length);
		}

		/// <summary>
		/// Creates a <c>dd</c>/<c>.int</c> asm directive
		/// </summary>
		/// <param name="data">Data</param>
		/// <param name="index">Start index</param>
		/// <param name="length">Number of elements</param>
		public static Instruction CreateDeclareDword(uint[] data, int index, int length) {
			if (data is null)
				ThrowHelper.ThrowArgumentNullException_data();
			if ((uint)length - 1 > 4 - 1)
				ThrowHelper.ThrowArgumentOutOfRangeException_length();
			if ((ulong)(uint)index + (uint)length > (uint)data.Length)
				ThrowHelper.ThrowArgumentOutOfRangeException_index();

			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareDword;
			instruction.InternalDeclareDataCount = (uint)length;

			for (int i = 0; i < length; i++)
				instruction.SetDeclareDwordValue(i, data[index + i]);

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}

		/// <summary>
		/// Creates a <c>dq</c>/<c>.quad</c> asm directive
		/// </summary>
		/// <param name="q0">Qword 0</param>
		public static Instruction CreateDeclareQword(ulong q0) {
			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareQword;
			instruction.InternalDeclareDataCount = 1;

			instruction.SetDeclareQwordValue(0, q0);

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}

		/// <summary>
		/// Creates a <c>dq</c>/<c>.quad</c> asm directive
		/// </summary>
		/// <param name="q0">Qword 0</param>
		/// <param name="q1">Qword 1</param>
		public static Instruction CreateDeclareQword(ulong q0, ulong q1) {
			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareQword;
			instruction.InternalDeclareDataCount = 2;

			instruction.SetDeclareQwordValue(0, q0);
			instruction.SetDeclareQwordValue(1, q1);

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}

#if HAS_SPAN
		/// <summary>
		/// Creates a <c>dq</c>/<c>.quad</c> asm directive
		/// </summary>
		/// <param name="data">Data</param>
		public static Instruction CreateDeclareQword(ReadOnlySpan<byte> data) {
			if ((uint)data.Length - 1 > 16 - 1 || ((uint)data.Length & 7) != 0)
				ThrowHelper.ThrowArgumentOutOfRangeException_data();

			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareQword;
			instruction.InternalDeclareDataCount = (uint)data.Length / 8;

			for (int i = 0; i < data.Length; i += 8) {
				uint v1 = data[i] | ((uint)data[i + 1] << 8) | ((uint)data[i + 2] << 16) | ((uint)data[i + 3] << 24);
				uint v2 = data[i + 4] | ((uint)data[i + 5] << 8) | ((uint)data[i + 6] << 16) | ((uint)data[i + 7] << 24);
				instruction.SetDeclareQwordValue(i / 8, (ulong)v1 | ((ulong)v2 << 32));
			}

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}
#endif

		/// <summary>
		/// Creates a <c>dq</c>/<c>.quad</c> asm directive
		/// </summary>
		/// <param name="data">Data</param>
		public static Instruction CreateDeclareQword(byte[] data) {
			if (data is null)
				ThrowHelper.ThrowArgumentNullException_data();
			return CreateDeclareQword(data, 0, data.Length);
		}

		/// <summary>
		/// Creates a <c>dq</c>/<c>.quad</c> asm directive
		/// </summary>
		/// <param name="data">Data</param>
		/// <param name="index">Start index</param>
		/// <param name="length">Number of bytes</param>
		public static Instruction CreateDeclareQword(byte[] data, int index, int length) {
			if (data is null)
				ThrowHelper.ThrowArgumentNullException_data();
			if ((uint)length - 1 > 16 - 1 || ((uint)length & 7) != 0)
				ThrowHelper.ThrowArgumentOutOfRangeException_length();
			if ((ulong)(uint)index + (uint)length > (uint)data.Length)
				ThrowHelper.ThrowArgumentOutOfRangeException_index();

			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareQword;
			instruction.InternalDeclareDataCount = (uint)length / 8;

			for (int i = 0; i < length; i += 8) {
				uint v1 = data[index + i] | ((uint)data[index + i + 1] << 8) | ((uint)data[index + i + 2] << 16) | ((uint)data[index + i + 3] << 24);
				uint v2 = data[index + i + 4] | ((uint)data[index + i + 5] << 8) | ((uint)data[index + i + 6] << 16) | ((uint)data[index + i + 7] << 24);
				instruction.SetDeclareQwordValue(i / 8, (ulong)v1 | ((ulong)v2 << 32));
			}

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}

#if HAS_SPAN
		/// <summary>
		/// Creates a <c>dq</c>/<c>.quad</c> asm directive
		/// </summary>
		/// <param name="data">Data</param>
		public static Instruction CreateDeclareQword(ReadOnlySpan<ulong> data) {
			if ((uint)data.Length - 1 > 2 - 1)
				ThrowHelper.ThrowArgumentOutOfRangeException_data();

			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareQword;
			instruction.InternalDeclareDataCount = (uint)data.Length;

			for (int i = 0; i < data.Length; i++)
				instruction.SetDeclareQwordValue(i, data[i]);

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}
#endif

		/// <summary>
		/// Creates a <c>dq</c>/<c>.quad</c> asm directive
		/// </summary>
		/// <param name="data">Data</param>
		public static Instruction CreateDeclareQword(ulong[] data) {
			if (data is null)
				ThrowHelper.ThrowArgumentNullException_data();
			return CreateDeclareQword(data, 0, data.Length);
		}

		/// <summary>
		/// Creates a <c>dq</c>/<c>.quad</c> asm directive
		/// </summary>
		/// <param name="data">Data</param>
		/// <param name="index">Start index</param>
		/// <param name="length">Number of elements</param>
		public static Instruction CreateDeclareQword(ulong[] data, int index, int length) {
			if (data is null)
				ThrowHelper.ThrowArgumentNullException_data();
			if ((uint)length - 1 > 2 - 1)
				ThrowHelper.ThrowArgumentOutOfRangeException_length();
			if ((ulong)(uint)index + (uint)length > (uint)data.Length)
				ThrowHelper.ThrowArgumentOutOfRangeException_index();

			Instruction instruction = default;
			instruction.InternalCode = Code.DeclareQword;
			instruction.InternalDeclareDataCount = (uint)length;

			for (int i = 0; i < length; i++)
				instruction.SetDeclareQwordValue(i, data[index + i]);

			Debug.Assert(instruction.OpCount == 0);
			return instruction;
		}
		// GENERATOR-END: Create
	}
}
#endif
